Reference
Teams
Teams let you collaborate on projects with other people under a shared subscription and a single billing relationship. This page covers everything an organization owner or admin needs to know: how teams work, the four roles, member management, usage tracking, plans, seats, and invoices.
On this page
What is a team
A team (sometimes called an organization internally) is a shared workspace owned by one person and joined by invitation. Members of a team can see and work on projects that belong to that team, without those projects living under any one person's personal account.
Teams are exclusive to the Team plan. The plan includes a baseline of 5 seats. Each accepted member beyond 5 is billed per seat on the same Team subscription, as a per-seat add-on that syncs automatically. There is a 14-day free trial. Members do not need their own paid subscription to be invited; the team's subscription covers them.
Resources (build minutes, CPU/RAM caps on running containers, log retention) are evaluated against the team's plan whenever a project is owned by the team, regardless of the personal plan of the user who created it.
Creating a team
After upgrading to the Team plan, the dashboard prompts you with a one-time onboarding wizard:
- Team name (shown across the UI).
- Slug (used in URLs like /o/your-team).
- Optional company domain (purely metadata; not enforced on member emails).
The user who creates the team becomes its Owner. Ownership is unique: a team has exactly one owner at any time. The owner is the only role that can transfer ownership, change billing, or delete the team.
Roles and permissions
Every member has exactly one role within a team. Four system roles ship with every team and cannot be edited or deleted. On top of those, owners can define unlimited custom roles with whatever mix of granular permission flags they want, from /dashboard/team/roles.
Higher system roles inherit everything lower ones can do. Custom roles are independent: pick exactly the flags you want.
Founder. Full control. Exactly one per team.
Can
- Everything an admin can do, plus billing access (Stripe portal, plan changes, payment methods).
- Transfer ownership to another member.
- Delete the team.
- Demote or remove other admins.
Operates the team day-to-day, without payment details.
Can
- Invite, remove, and re-role members (except the owner and other admins).
- Create, edit, deploy, and delete projects.
- Edit team settings: name, tagline, accent color, featured links, public profile toggle.
- View usage analytics.
Cannot
- Billing tab (cannot open Stripe portal, change plan, or download invoices).
- Act on the owner or another admin.
The default working role.
Can
- Create new projects under the team.
- Deploy, redeploy, view logs, edit env vars on team projects.
- Edit project settings (domain, build, runtime).
- View usage analytics.
Cannot
- Member management (cannot invite, remove, or re-role).
- Team settings (cannot edit the public profile or branding).
- Billing tab and Invoices tab.
Read-only access. Auditors, observers, stakeholders.
Can
- View projects, deployments, logs, env-var keys (values masked).
- View audit log.
- View usage analytics.
Cannot
- Any write action: no deploys, no env edits, no project changes.
- Member management, team settings, billing, invoices.
Custom roles
Open /dashboard/team/roles as an owner (or anyone with the roles.manage permission) and click New custom role. You pick a name, optional description, and tick exactly the granular permissions you want.
The permissions catalog covers project lifecycle, deploys, logs, env vars, domains, services, team management, billing, usage, and audit. Each flag is a separate checkbox so a role like "Senior dev" can have everything a Developer has plus members.invite, without unlocking billing.
Members can be assigned a custom role from the Members tab dropdown. Deleting a custom role demotes its members back to the legacy system role (typically developer) so nobody is stranded without access.
Heads up
The roles.manage permission lets a holder elevate themselves by editing a role they already have. Grant it carefully; if in doubt, keep it on Owner + Admin only.
Inviting members
From /dashboard/team (Members tab), an owner or admin clicks Invite member, enters the invitee's email, and picks the role they will join with. The invitee receives a token-based link they can open while signed in (or while signing up) to accept.
Invites expire after 14 days if not accepted. Pending invites count toward your seats, so each one you send is reflected in the per-seat math right away. Revoke a pending invite by clicking the trash icon next to it; that frees up the seat immediately.
Seat math
Seats used = active members + pending invites. The Team plan includes a baseline of 5 seats. With an active subscription you can go past the baseline freely: seats beyond your included 5 are billed per seat on your Team subscription. Teams without an active subscription stay capped at the baseline.
Projects under a team
A project belongs either to a personal account or to one team. When you are in team context (selected via the team switcher), new projects created from the dashboard or the CLI are owned by the team automatically.
Existing personal projects can be transferred into a team and back out again from the project settings page. The transfer is atomic: ownership and resource limits flip in a single transaction so a project never lands in an inconsistent state.
Resource caps (CPU, RAM, build minutes) are evaluated against the project's current owner. A project transferred from a Hobby personal account into a Team-plan org immediately gets the team's higher caps on its next deploy.
Usage tab
The Usage tab at /dashboard/team/usage reports a rolling 30-day window across all projects owned by the team. Every member of the team can view this tab (including viewers), so the whole org can see how loaded the workspace is.
Deployments
count
Number of deployment rows with status terminal (live, failed, cancelled, timeout) created in the last 30 days for any project owned by this team. Failed and cancelled runs are counted because they still consumed build minutes.
Build minutes
sum of (finished_at − created_at), capped per row
For each completed deployment we sum the wall-clock time from when it was queued to when it finished, expressed in minutes. We cap any single deployment at 600 minutes so a clock skew cannot blow up the total.
Projects
count
How many project rows have this team as their owner (organization_id).
Services
count of database services
Subset of projects whose template is one of postgresql, mariadb, or redis. These are the managed databases provisioned through Add Service.
Per-member breakdown
The per-member table attributes each project's deploys, build minutes, and project count to the user who owns the project row in the database. This is a useful approximation but not a perfect "who deployed what".
Concretely: if Alice creates project radio-banat and Bob deploys to it later, both the deploy and the build minutes show up under Alice in the per-member table, because Alice is the project owner. The platform does not currently record the user who triggered each individual deploy.
Quick recap of the math
for each project P owned by the team: D(P) = count of P deployments in last 30 days with finished_at set M(P) = sum over those deployments of (finished_at - created_at), in minutes team.deploys += D(P); team.minutes += M(P) perMember[ P.owner_user_id ] += D(P), M(P), 1 project
Build minute cap
The Usage tab renders a progress bar against the build-minute cap defined by your plan. Right now the caps are:
Hobby
100 minutes / month
Developer
1000 minutes / month
Team
no cap (fair use)
The cap is informational: deploys past the cap are not currently hard-blocked. If a team consistently consumes well over its plan's expected minutes, we may reach out before any enforcement is added.
Recent activity feed
Below the per-member table, Usage shows the 10 most recent deployments across the team with their status, project name, commit message, and relative timestamp. This is the same data the project page's deployment history shows, but aggregated team-wide for a quick "what's happening right now" glance.
Billing tab
The Billing tab at /dashboard/team/billing is restricted to owners and admins. Viewers and developers see an inline notice instead.
Plan
Team / €39 mo base
The base monthly cost of the subscription before any per-seat charges for members beyond the included 5. Plans cannot currently be changed in-app for teams; contact support if you need to switch.
Status
active / past_due / canceled / trialing
Mirrors the Stripe subscription status. Renews automatically on the period end date unless you cancel from the customer portal. past_due means a payment failed; resolve by updating your card.
Seats
used / baseline
Active members + pending invites against the 5-seat baseline. Seats beyond your included 5 are billed per seat on your Team subscription, kept in sync automatically as members join or leave.
Next invoice estimate
amount due on the next renewal
A best-effort preview from Stripe of what the next invoice will be, including the current per-seat charges for members beyond the included 5. The figure refreshes when you reload the page.
The Manage subscription button opens the Stripe Customer Portal in a new tab. From there you can update the card, change billing email, cancel at period end, or download past invoices directly. The portal redirects back to the team page when you are done.
Invoices tab
The Invoices tab at /dashboard/team/invoices lists the last 20 invoices Stripe has issued to this team, with their status, period, paid amount, and two links per row: open the hosted invoice page, or download the PDF directly.
Like Billing, this tab is restricted to owners and admins. A team that has not yet issued its first invoice (e.g. created during a trial) sees a friendly empty state.
Invoice statuses follow Stripe's vocabulary:
Charged successfully. PDF is final.
Issued but not yet paid (within the retry window, or awaiting a fixed payment method).
Stripe gave up retrying. Common after multiple payment failures; the team is moved to past_due until resolved.
Cancelled before being paid. No charge will be attempted.
Not yet finalised. Should be transient.
Switching between teams
You can belong to multiple teams at once. The header on every /dashboard/team/* page shows a row of pill buttons, one per team you are in; click any to switch context. The choice persists across page loads and influences which projects show up on your dashboard.
When you have only one team, the switcher is hidden to reduce visual noise.
Leaving or deleting a team
Any non-owner member can leave a team from their own row in the Members tab (the icon next to your name turns into a Leave button). Leaving is immediate; you lose access to all projects owned by that team. Your personal projects are unaffected.
The owner cannot leave directly. To exit, the owner first transfers ownership to another existing member (a button on the target member's row, once promoted to admin), then leaves like anyone else.
Deleting an entire team is owner-only and removes every project, deployment, domain, and member record belonging to it. The Stripe subscription is cancelled at period end, not immediately, so the team keeps access through the paid window. Deletion cannot be undone; an export tool for projects is on the roadmap.