LofentaLofenta/Docs

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:

  1. Team name (shown across the UI).
  2. Slug (used in URLs like /o/your-team).
  3. 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.

Owner

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.
Admin

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.
Developer

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.
Viewer

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:

paid

Charged successfully. PDF is final.

open

Issued but not yet paid (within the retry window, or awaiting a fixed payment method).

uncollectible

Stripe gave up retrying. Common after multiple payment failures; the team is moved to past_due until resolved.

void

Cancelled before being paid. No charge will be attempted.

draft

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.