Xeonr Developer Docs
API Specification

Teams

Buckets and access keys owned by a Xeonr team rather than an individual.

A bucket in upl.im belongs either to you or to a team. Teams live in Xeonr Auth — membership, invitations and roles are managed there, and upl.im reads them.

Team ownership exists so that shared content genuinely belongs to the group. A team-owned bucket has no owning user at all: access follows the roles people hold in the team, so nobody keeps a private claim on it after they move on.

Roles

upl.im defines three team roles in Xeonr Auth. Assign them per member, on the team's page in the auth portal.

RoleCan do
adminEverything: bucket settings, aliases, access keys, deletion, and transferring the bucket
writerRead and write files
readerRead files

Role names are matched case-insensitively, so admin and ADMIN are the same role. (Xeonr Auth already treats them as the same name, so the two cannot coexist on one application.)

Roles are explicit. Belonging to a team grants nothing on its own — a member with none of these roles cannot see the team's buckets. That is deliberate: adding somebody to a team should never silently hand them content.

Getting a token that can see teams

Team membership reaches upl.im through the auth:teams:read scope. Request it alongside your other scopes:

openid profile email offline_access
upl:bucket:read upl:uploads:create upl:uploads:manage
auth:teams:read

Without it, a token sees only personal buckets. Team-owned buckets are not merely unwritable — they are invisible, and any request naming one is refused. The first-party dashboard, CLI, desktop and mobile clients all request it already; a session created before you added the scope needs a fresh sign-in.

Note that client_credentials and service-account tokens never carry team membership, so they cannot reach team-owned buckets.

Working with a team's buckets

Every bucket-scoped RPC works exactly as it does for a personal bucket; the permission level is simply derived from your team role instead of ownership.

ListBuckets returns personal and team buckets together, each carrying owner_team (the team's URN) and owner_team_slug. To list one owner's buckets, set owner_scope:

{ "owner_scope": { "team": "urn:xeonr:auth:team:0f3c…" } }
{ "owner_scope": { "personal": true } }

Omitting owner_scope returns everything you can see, which is what clients written before teams existed continue to get.

CreateBucket takes an optional owner_team; supply a team URN to create the bucket under that team. It requires the admin role there.

Moving a bucket

MoveBucket transfers a bucket between owners — personal to a team, between teams, or back to you. You need admin on the bucket, plus the admin team role in each team involved.

The bucket's slug, aliases, share links and every existing URL are unchanged. Ownership is the only thing that moves, so nothing needs re-pointing afterwards: existing ShareX configs, embeds and aws profiles keep working.

Two things to know before moving:

  • Grants you have given to individuals (via GrantBucketPermission or a resource grant) are preserved — sharing is separate from ownership.
  • Access-key grants that would cross the new ownership boundary are revoked, because a personal key may not hold a team bucket and vice versa. The call fails first and names the affected keys; retry with revoke_conflicting_grants: true to proceed.

Freshness

Read operations are authorised from the team membership carried on your access token, so a role change takes effect when your client next refreshes — within the access-token lifetime. Anything requiring admin — deletion, settings, access keys, transfers — is checked against Xeonr Auth at the moment of the request, so a revoked admin cannot act on a stale token.

Third-party apps requesting access

An app asking for a bucket by authorization_details (Rich Authorization Requests) is approved against your personal access to that bucket only. Team roles are not read on the consent screen, so consenting to write access for a team-owned bucket is refused even when you hold admin in the team.

Read access still works where the bucket serves anonymous traffic. To grant an app write access to a team's bucket today, give it an access key owned by that team instead — see Access keys.

On this page