Projects
Overview
Projects let you segment your AI traffic into logical groups — by product, feature, team, or any other dimension that makes sense for your organization. Each project gets its own dashboard views, cost tracking, quality metrics, API keys, and team membership.
When a request passes through the Floopy gateway, it is tagged with a project ID. This ID flows through to ClickHouse, where every analytics query can be scoped to a single project or compared across all projects.
Key Concepts
Projects are environment-agnostic. The environment (development, staging, production, other) is a property of the API key, not the project. This means a single project like “Checkout” can have separate keys for dev and prod, and the cost-by-environment widget splits spend across environments natively.
Every organization has a Default project. Created automatically when the org is provisioned. Legacy traffic (requests without a project ID) is attributed to the Default project.
The floopy-project-id header is optional. If your API key is hard-locked to a project, that project is used automatically. Otherwise, the gateway resolves the project using a fallback chain: header → key’s default project → Default project.
Creating a Project
Create projects from the dashboard at Projects > New Project. Each project has:
- Name — Display name (up to 100 characters)
- Slug — URL-safe identifier (lowercase letters, numbers, hyphens, up to 63 characters)
- Description — Optional, up to 500 characters
- Color and Icon — For visual identification in the dashboard
Plan Quotas
| Plan | Max Projects |
|---|---|
| Free | 1 |
| Starter | 3 |
| Pro | 10 |
| Enterprise | Unlimited |
Sending the floopy-project-id Header
Pass a project UUID in the floopy-project-id header to tag requests with a specific project.
curl https://api.floopy.ai/v1/chat/completions \ -H "Authorization: Bearer $FLOOPY_API_KEY" \ -H "Content-Type: application/json" \ -H "floopy-project-id: a1b2c3d4-5678-9abc-def0-123456789abc" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}] }'response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Hello"}], extra_headers={ "floopy-project-id": "a1b2c3d4-5678-9abc-def0-123456789abc", },)const response = await client.chat.completions.create( { model: "gpt-4o", messages: [{ role: "user", content: "Hello" }], }, { headers: { "floopy-project-id": "a1b2c3d4-5678-9abc-def0-123456789abc", }, },);req, _ := http.NewRequest("POST", "https://api.floopy.ai/v1/chat/completions", body)req.Header.Set("Authorization", "Bearer "+os.Getenv("FLOOPY_API_KEY"))req.Header.Set("Content-Type", "application/json")req.Header.Set("floopy-project-id", "a1b2c3d4-5678-9abc-def0-123456789abc")
resp, err := http.DefaultClient.Do(req)Fallback Chain
The gateway resolves the project ID using this priority:
- Hard-locked key — If the API key has a
project_idset, that project is always used. Afloopy-project-idheader that differs from the locked project returns 403 Forbidden. - Header — The
floopy-project-idrequest header. - Key default — The API key’s
default_project_idfield. - Organization default — The organization’s Default project (zero UUID sentinel).
graph TD
A[Request arrives] --> B{Key has project_id?}
B -->|Yes| C{Header matches?}
C -->|Yes or no header| D[Use locked project]
C -->|Different UUID| E[403 Forbidden]
B -->|No| F{Header present?}
F -->|Yes| G[Use header project]
F -->|No| H{Key has default_project_id?}
H -->|Yes| I[Use key default project]
H -->|No| J[Use org Default project]Per-Project API Keys
Instead of passing the floopy-project-id header on every request, you can create API keys that are hard-locked to a project. Every request using that key is automatically attributed to the locked project — no header needed.
This is the recommended approach for production. Create one key per project per environment:
| Key Name | Project | Environment |
|---|---|---|
checkout-dev | Checkout | development |
checkout-prod | Checkout | production |
search-prod | Search | production |
Hard-locked keys enforce project isolation at the gateway level. A request that sends a different floopy-project-id header is rejected with 403 Forbidden.
Environment Model
Environments are a property of the API key. When you create or edit an API key, you can optionally set its environment to one of: development, staging, production, or other.
The environment is stamped on every request log. This lets you:
- Filter dashboard views by environment
- Compare cost across environments for the same project
- Set per-environment rate limits (RPM) and monthly cost caps
Environment Limits
Configure per-environment RPM and monthly USD cost caps in Settings > Limits. When a cost cap is breached, the gateway returns 402 Payment Required for all requests using keys tagged with that environment until the cost drops below 95% of the limit (5% hysteresis).
| Setting | Description |
|---|---|
| Rate Limit RPM | Maximum requests per minute for all keys in this environment |
| Monthly Cost USD | Maximum monthly spend across all keys in this environment |
Per-Project Dashboards
When you select a project in the project switcher, all dashboard pages (requests, sessions, users, properties, cache, rate limits, security, evaluations) are filtered to show only that project’s data.
In single-project mode, five additional widgets appear:
- Cost Comparison — Project cost per million tokens vs. org average
- Quality Comparison — Feedback score vs. org average
- Latency Comparison — Average latency vs. org average
- Project Rank — Percentile rank across all org projects
- Cost by Environment — Stacked breakdown of spend by environment, with progress bars against environment cost caps
In “All Projects” mode, a projects breakdown table shows per-project metrics side by side.
Manager Role
The manager organization role sits between admin and member. Managers can:
- Create new projects (up to the plan limit)
- Manage projects they are assigned to
Managers cannot access organization settings, billing, or provider configuration. Assign the manager role to team leads who need to create and manage their own projects without full org admin access.
Project Members and Roles
Each project has its own membership list with three roles:
| Role | Permissions |
|---|---|
| Owner | Full control including project deletion |
| Admin | Manage members, API keys, and settings |
| Member | View project data and dashboards |
Org owners and admins have implicit admin access to every project — they are not listed in the project members table unless they explicitly join.
Project membership is managed from the project’s Members tab. Only project owners and admins (or org owners/admins) can add or remove members.
Per-Project Budgets and Alerts
Team budgets and alerts can be scoped to a specific project. When a budget is project-scoped:
- Cost computation only counts requests tagged with that project
- Auto-revoke on breach only revokes API keys associated with that project
- The budget appears with a project badge in the team budgets listing
Similarly, alerts can be scoped to trigger only when a project exceeds a threshold.
Best Practices
- One project per product or feature — “Checkout AI”, “Search”, “Content Generation”
- One API key per project per environment — Enables environment-level cost tracking without any code changes
- Use hard-locked keys in production — Eliminates the need for the header and prevents accidental cross-project attribution
- Assign the manager role to team leads — Lets them create projects without org admin access
- Set environment cost caps early — Prevents runaway costs in production before they hit your billing
Plan Requirements
| Feature | Free | Starter | Pro | Enterprise |
|---|---|---|---|---|
| Projects | 1 | 3 | 10 | Unlimited |
| Per-project dashboards | Yes | Yes | Yes | Yes |
| Per-project API keys | Yes | Yes | Yes | Yes |
| Environment limits | Yes | Yes | Yes | Yes |
| Project members | Yes | Yes | Yes | Yes |
| Team budgets per project | Yes | Yes | Yes | Yes |