Platform
Teams
A team is a shared workspace: every pack it owns belongs to everybody on it, everybody spends from one pool of AI Credits, and it all arrives on one invoice.
It's the other half of Collaborators, not a bigger version of it. A collaborator is somebody you let into one pack, with a chosen slice of it. A team is the arrangement where that stops making sense — five people who work on everything together, where granting each of them access to eleven packs one at a time is the friction rather than the safety.
Both still exist and they don't overlap. Somebody on the team gets every team pack automatically. Somebody outside it can still be invited to a single team pack as an ordinary collaborator, with the same sections and capabilities as anywhere else — and they don't use up a seat.
What it costs#
$30 per seat, per month. Minimum two seats, because everything a team adds is about there being somebody else.
Each seat adds 1,000 AI Credits a month to the shared pool. A five-seat team gets 5,000 a month between them, spent by whoever needs them — there is no per-person allowance to run out of while somebody else's goes unused.
Top-ups are 40% off on a team, the best rate in the product. Only the owner can buy them.
A seat doesn't replace a plan of your own. The two bill separately and you can hold both — your own packs run on your own plan, the team's packs run on the team's, and the switcher decides which one you're working in. Nothing about your account changes when you join a team.
Switching between your packs and the team's#
Bottom-left of the sidebar, where your name and credit balance are. Click it and you get a list: Personal, then every team you're on.
Whatever you pick is the context everything else follows. The pack list, the New pack button, the credit balance in the corner, the limits — all of them mean "yours" or "the team's" depending on which one is selected.
A pack is created in whichever context is active and stays there. Make a pack while you're in the team and it's the team's from the moment it exists, listed for everybody. Make one in your personal context and it's yours alone. There is no moving a pack between the two yet.
Roles#
Everything an admin can do, plus billing: seats, top-ups, cancelling. One per team, and only the owner can hand it to somebody else.
Invite and remove people, change roles, publish packs, delete packs.
Full edit on every team pack, and spends from the pool.
Opens every team pack and changes nothing — no editing, no generating, no exporting. For clients and contractors.
Membership is the grant — there is nothing to configure per person, which is most of the point. A member sees every section of every team pack and can edit, generate, sync and export in all of them. The two things reserved for admins are the ones that are hard to undo: publishing a pack to somebody's players, and deleting one.
Seats#
You buy seats, then fill them. Removing somebody frees their seat immediately and that seat can be refilled at no extra cost.
An empty seat is still a paid seat. Removing a person doesn't reduce your bill — the seat is yours for the rest of the month you've paid for. Reducing the number of seats is a separate thing you do on the team's page.
Changing the seat count is deliberately not symmetrical:
- Adding a seat takes effect straight away. You're charged the prorated part of the month, and the extra 1,000 credits land in the pool.
- Removing a seat can happen either way. Now takes effect immediately and refunds nothing — which is exactly why no credits come back out of the pool either; you paid for the month, you keep the month. At renewal keeps the seats you've already paid for until the period ends, then drops to the new number. Unless you specifically want the smaller number reflected today, at renewal is the one you want.
Inviting somebody#
Open the team's page and invite them by email. Invitations last fourteen days and can be withdrawn at any time.
An invitation holds a seat while it's outstanding, so you can't invite four people to a two-seat team and let them race for it.
Inviting by email always says "invitation sent", whether or not that address already has an account here — the same rule as a pack invitation, and for the same reason. Otherwise the box would tell anybody who typed an address whether its owner has a resourcepack.ai account.
Limiting somebody to certain packs#
An admin can restrict a member or viewer to a chosen set of packs, from the members list. By default nobody is restricted, and that's the normal way to run a team — being on it is the access.
It's an allowlist, so a pack made after you set the restriction isn't one they can see. That's deliberate: a contractor shouldn't silently gain access to next month's project. Admins and owners can't be restricted, because managing every pack is what being an admin means.
Spend limits#
An admin can cap what any one person takes out of the pool in a billing period. Set it from the members list on the team's page; leave it blank for no limit, which is the default.
Everybody can see their own limit and how much of it they've used, so nobody finds out about a cap by being refused halfway through a generation.
The owner can't be limited. They hold the card, so a cap on them is one they could lift in a click — a limit that only pretends to bind is worse than none at all.
Your own API key, and your own OpenAI key#
Both work per context, the same way packs and credits do.
API keys — create one while you're in the team and it belongs to the team: it spends the pool and reaches the team's packs, rather than dying with whoever made it. Admins only, to create and to revoke. If somebody leaves the team, every team key they were holding stops working immediately.
Your own OpenAI key — a team can store one, and then anything that can run on it costs the pool nothing. Admins can set it. A team pack always uses the team's key, never a member's personal one.
Activity and spend#
Every team has an Activity page with two tabs, and everybody on the team can read both.
Audit log — who invited whom, who changed a role, who published or deleted a pack, when the seat count moved, who set a spend limit, who changed the team's API keys, who renamed it. Written as things happen, so it's a record rather than a reconstruction.
Spend — how many credits each person has used this billing period, and how many actions that was. This is the answer to "where did the pool go", which is the question a shared balance creates.
Viewers don't get this page — it's the team's billing history and everybody's addresses, and a viewer can't spend the pool in the first place.
Both tabs have an Export CSV button, which gives you the entire history rather than what's on screen — the version to hand whoever reconciles the invoice.
Automatic top-ups#
The pool running out stops everybody at once, and only the owner can fix it. So the owner can set a floor and an amount: when the shared balance drops below the floor, we buy that many credits on the team's card and carry on.
Capped at three automatic purchases per billing period, so a mistake can't run away with your card, and every one of them emails the owner and lands in the audit log. A team whose plan has lapsed is never charged.
Webhooks#
Admins can point the team's activity at a URL — everything the audit log records gets POSTed there as JSON, which is how you get it into Slack, Discord or your own tooling. Add them on the team's Settings page; a team can have several (up to five), each with its own signing secret shown once when you add it. Every event is delivered to all of them.
The request#
Each event is a POST with a JSON body and these headers:
Content-Type: application/json
User-Agent: resourcepack.ai-webhook/1
X-RPAI-Signature: sha256=<hex>The body is one event:
{
"type": "pack.published",
"team": "a1b2c3d4",
"actor": "user_9f8e7d",
"target": "ruined_kingdom",
"detail": { "version": 3 },
"id": "b7c1e0f2-…",
"at": "2026-08-23T14:02:11.904Z"
}typeis the action — the same vocabulary the audit log and the CSV export use (member.joined,member.role_changed,seat.changed,pack.published, and so on).actoris the account id that did it, ornullfor a system event.targetanddetailvary by type:targetis what it happened to (a pack name, the person a role changed for),detailis any extra fields that type carries, ornull.idis unique per delivery — use it to dedupe, since delivery is at-least-once in spirit rather than exactly-once.atis when it was sent, ISO 8601.
Verifying the signature#
X-RPAI-Signature is sha256= followed by the hex HMAC-SHA256 of the
raw request body, keyed with your signing secret. Compute the same over the
bytes you received and compare — if they don't match, it isn't from us. Verify
against the raw body, not a re-serialized copy of the parsed JSON, or a
re-ordered key will fail a signature that was actually valid.
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(header ?? "");
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}Delivery#
https only, and we won't POST to loopback or private-network addresses. Each
attempt times out after five seconds, and delivery is best effort with no
retry — a receiver that's down loses that event rather than blocking the
action that produced it. If you need a guaranteed complete record, the CSV
export is it. The Settings card shows the last delivery's status so you can
tell whether your endpoint is answering.
Leaving, and what happens to the packs#
Anybody except the owner can leave a team from its page, and an admin can remove anybody except the owner.
If you're the owner and you want to leave, hand the team over first: open the members list and press Make owner on somebody. Seats, top-ups and cancelling all move to them, and you become an admin.
The packs stay with the team. They were never one person's — a pack made in a team context belongs to the team from the moment it's created, so somebody leaving takes nothing with them and there's nothing to hand over.
If the team's plan lapses, nothing is deleted. The packs stay, everybody keeps their access, and whatever credits the pool had accumulated stay in it — what stops is making new things, exactly as it would for a personal account that lapsed to Starter.