Overview
Projects are containers that organize related secrets. They help you manage access control and group secrets logically.
List Projects
Retrieve all projects in an organization.
GET /organizations/{organizationId}/projects
Response
Returns all projects accessible to the current user or service account.
Project unique identifier
Whether user has read access
Whether user has write access
Get Project
Retrieve a specific project by ID.
curl -X GET "https://api.bitwarden.com/projects/{id}" \
-H "Authorization: Bearer {access_token}"
Create Project
Create a new project.
curl -X POST "https://api.bitwarden.com/organizations/{organizationId}/projects" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Environment"
}'
Request Body
Response
Returns the created project with read and write both set to true (creator has full access).
The number of projects you can create depends on your Secrets Manager plan.
Update Project
Update an existing project.
Request Body
curl -X PUT "https://api.bitwarden.com/projects/{id}" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Production - Updated"
}'
Delete Projects
Delete one or more projects.
Array of project IDs to delete
Response
Returns results for each deletion attempt:
{
"data": [
{
"id": "project-guid-1",
"error": ""
},
{
"id": "project-guid-2",
"error": "access denied"
}
]
}
Deleting a project removes all secrets within it. This action cannot be undone.
Project Organization
By Environment
- Production
- Staging
- Development
- Testing
By Application
- Web Application
- Mobile App - iOS
- Mobile App - Android
- Background Workers
By Team
- Engineering Team
- DevOps
- Data Science
- QA Team
Access Control
Projects support granular access control through access policies.
Grant User Access
Allow specific users to access a project:
{
"userAccessPolicies": [
{
"organizationUserId": "user-guid",
"read": true,
"write": false
}
]
}
Grant Group Access
Allow groups to access a project:
{
"groupAccessPolicies": [
{
"groupId": "group-guid",
"read": true,
"write": true
}
]
}
Grant Service Account Access
Allow service accounts to access a project:
{
"serviceAccountAccessPolicies": [
{
"serviceAccountId": "sa-guid",
"read": true,
"write": false
}
]
}
Best Practices
Naming Conventions
Use clear, consistent names:
[Environment] - [Application/Service]
Examples:
Production - Web API
Staging - Mobile App
Development - Database
Testing - E2E Tests
Access Strategy
- Least Privilege: Grant minimum required access
- Use Groups: Assign access to groups, not individuals
- Separate Environments: Don’t mix prod and dev in same project
- Service Accounts: Use for automation, limit to specific projects
Organization
- One Project per Environment: Separate production, staging, development
- Limit Scope: Keep projects focused on a single app/service
- Document Purpose: Use clear names that explain project purpose
- Regular Audits: Review project access periodically
Usage Examples
Create Environment Projects
const environments = ['Production', 'Staging', 'Development'];
for (const env of environments) {
await fetch(
`https://api.bitwarden.com/organizations/${orgId}/projects`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: env })
}
);
}
List Projects with Secrets Count
import requests
response = requests.get(
f"https://api.bitwarden.com/organizations/{org_id}/projects",
headers={"Authorization": f"Bearer {token}"}
)
projects = response.json()['data']
for project in projects:
# Get secrets for each project
secrets_response = requests.get(
f"https://api.bitwarden.com/projects/{project['id']}/secrets",
headers={"Authorization": f"Bearer {token}"}
)
secret_count = len(secrets_response.json()['data'])
print(f"{project['name']}: {secret_count} secrets")
Migrate Secrets to New Project
#!/bin/bash
# Get all secrets from old project
OLD_SECRETS=$(curl -s "https://api.bitwarden.com/projects/${OLD_PROJECT_ID}/secrets" \
-H "Authorization: Bearer ${TOKEN}")
# Update each secret to new project
echo $OLD_SECRETS | jq -r '.data[].id' | while read SECRET_ID; do
curl -X PUT "https://api.bitwarden.com/secrets/${SECRET_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "$(echo $OLD_SECRETS | jq ".data[] | select(.id==\"$SECRET_ID\") | .projectIds=[\"$NEW_PROJECT_ID\"]")"
done
Limits
Project limits vary by plan:
| Plan | Maximum Projects |
|---|
| Free (trial) | 3 |
| Teams | Unlimited |
| Enterprise | Unlimited |
Contact sales to increase limits or upgrade your plan.