# Team

Base URL `https://pfcloud.pfctek.com/api/v1`. Every call needs `Authorization: Bearer mf_…`. Changes accept an `Idempotency-Key` header. Ids are public ids (UUIDs).

## GET /team

**The team**

Scope: `team:read`

Name, plan, features, and each limit with current usage (pending invitations count as members).

## GET /team/members

**Members**

Scope: `team:read`

Name, email, role, permissions and access limits (public ids of servers and sites; null = everything). Changing roles or removing members is not available through the API: owners do it in the dashboard.

## GET /team/invitations

**Pending invitations**

Scope: `team:read`

Id, email, role and expiry. Invitation links are never returned.

## POST /team/invitations

**Invite someone**

Scope: `team:write`

Same rules as the dashboard: any role except owner, the plan's member limit, at most 20 invitations an hour per team.

| Body field | Type | Description |
| --- | --- | --- |
| `email` | string |  |
| `role` | string |  |

## DELETE /team/invitations/{invitation}

**Cancel an invitation**

Scope: `team:write`

| Parameter | In | Description |
| --- | --- | --- |
| `invitation` | path | Invitation id (required) |

## GET /team/notifications

**Where alerts go**

Scope: `team:read`

Whether Slack is on, and the chat channels' names and types. Webhook URLs, bot tokens and secrets are never returned.

## GET /audit-log

**Activity log**

Scope: `team:read`

Newest first, 50 a page (follow links.next). Needs the maker's "View audit log" permission.

| Parameter | In | Description |
| --- | --- | --- |
| `area` | query | Only this area |
| `user` | query | A member's email, or "automatic" for git pushes and pfcloud itself |
| `from` | query | Date or time, inclusive |
| `until` | query | Date or time, inclusive |
| `page` | query | Page number |

## GET /audit-log/verify

**Activity log integrity**

Scope: `team:read`

The last nightly check of the tamper-evident chain: {ok, problem, checked_at}, or null when it hasn't run yet.

