Projects
Projects group related work inside one workspace without making project assignment mandatory.
Projects are an optional organization layer inside a workspace. Jobs, files, workflows, workflow runs, Studio sessions, and AI conversations can belong to one project or remain unassigned.
Every resource still belongs to the API key workspace. A project never changes workspace permissions, billing, credits, or storage ownership.
Project routes
The Projects API supports project metadata, resource assignment, and deletion operations.
Use GET /api/v1/projects to list projects and PATCH /api/v1/projects/assignments to organize supported resources.
Project lists are cursor paginated. Use limit (1–100), then pass the returned next_cursor as starting_after while has_more is true. The optional q parameter searches names, descriptions, and project IDs.
| Method | Route | Purpose |
|---|---|---|
GET | /api/v1/projects | List active projects |
POST | /api/v1/projects | Create a project |
GET | /api/v1/projects/{projectId} | Read project metadata and resource counts |
PATCH | /api/v1/projects/{projectId} | Update a project name or description |
DELETE | /api/v1/projects/{projectId} | Start a project deletion operation |
PATCH | /api/v1/projects/assignments | Move resources to a project or leave them unassigned |
GET | /api/v1/project-deletions/{operationId} | Read a deletion operation |
POST | /api/v1/project-deletions/{operationId} | Retry a recoverable deletion operation |
Read routes require projects:read. Write routes require projects:write and the matching workspace permission.
Create a project
Use POST /api/v1/projects with a name and optional description.
curl -s -X POST \
-H "Authorization: Bearer $PROTEINIQ_API_KEY" \
-H "Content-Type: application/json" \
"https://proteiniq.io/api/v1/projects" \
-d '{
"name": "Kinase screening",
"description": "Docking and follow-up analysis"
}'Names are trimmed, contain 1 to 80 characters, and are unique within a workspace without regard to case. Descriptions may contain up to 500 characters.
The response includes counts for every supported resource type:
{
"id": "project_123",
"object": "project",
"name": "Kinase screening",
"description": "Docking and follow-up analysis",
"counts": {
"jobs": 4,
"files": 8,
"workflows": 1,
"workflow_runs": 3,
"studio_sessions": 0,
"ai_conversations": 2
},
"created_at": "2026-07-25T08:00:00.000Z",
"updated_at": "2026-07-25T09:00:00.000Z"
}Assign resources
Use PATCH /api/v1/projects/assignments to move jobs, files, workflows, workflow runs, Studio sessions, or AI conversations. Set target_project_id to null to leave the selected resources unassigned.
{
"target_project_id": "project_123",
"resources": [
{
"type": "job",
"ids": ["job_123"]
},
{
"type": "file",
"ids": ["file_123"]
}
],
"move_linked_files": true
}The request requires projects:write plus the write scope for every resource type:
- Jobs, workflows, and workflow runs:
jobs:write - Files:
files:write - Studio sessions and AI conversations: no additional resource scope
move_linked_files applies when jobs are selected. When true, saved files linked to those jobs move to the same destination. Moving a file never moves its source job.
Each request can select at most 500 resources. Every selected resource and destination project must belong to the API key workspace.
Use projects with other resources
Job, file, workflow, and workflow-run resources include project_id. A null value means the resource is unassigned.
- Create a job: Add optional
project_idtoPOST /api/v1/jobs - Upload a file: Add optional
project_idto the multipart form forPOST /api/v1/files - Start a workflow run: Add optional
project_idtoPOST /api/v1/workflows/{workflowId}/runs - Filter lists: Add
project_id=<id>to job, file, or workflow list routes - Find unassigned resources: Add
unassigned=trueto those list routes
Do not combine project_id and unassigned=true in one list request.
Creating a resource with a non-null project_id requires projects:write in addition to that resource's normal write scope. Omitting project_id keeps direct jobs and uploads unassigned. A workflow run inherits its workflow project unless the request supplies an override; any explicit workflow-run project_id, including null, requires projects:write.
Delete a project
Project deletion requires owner or admin permission. Send one of three modes to DELETE /api/v1/projects/{projectId}:
move: Move direct project resources totarget_project_id, then delete the projectunassign: Leave direct project resources in the workspace without a projectdelete_contents: Delete the project and its contents using the existing resource deletion behavior
{
"mode": "move",
"target_project_id": "project_456"
}Deletion is rejected while affected jobs or workflow runs are active. Collections remain workspace-wide. Deleting project files removes their collection links but does not delete the collections.
The endpoint returns a project_deletion resource. Read it through GET /api/v1/project-deletions/{operationId} when a client needs to confirm the final state. If a failed operation returns "retryable": true, retry its cleanup with POST /api/v1/project-deletions/{operationId}. Retrying requires projects:write and owner or admin permission.
{
"id": "deletion_123",
"object": "project_deletion",
"project_id": "project_123",
"project_name": "Kinase screening",
"mode": "unassign",
"target_project_id": null,
"status": "completed",
"error": null,
"attempt_count": 1,
"next_attempt_at": null,
"retryable": false,
"created_at": "2026-07-25T10:00:00.000Z",
"started_at": "2026-07-25T10:00:00.000Z",
"completed_at": "2026-07-25T10:00:01.000Z",
"updated_at": "2026-07-25T10:00:01.000Z"
}