Projects API
The Projects API allows you to create, manage, and execute data analysis projects. Projects contain steps, connectors, and execution history.
Base URL
Section titled “Base URL”All endpoints are prefixed with /api and routed through Traefik reverse proxy:
https://api.querri.com/apiAuthentication
Section titled “Authentication”All Projects API endpoints require JWT authentication. See Authentication for details.
Endpoints
Section titled “Endpoints”Create Project
Section titled “Create Project”Create a new project in your organization.
POST /api/projectsHeaders:
Authorization: Bearer {JWT_TOKEN}Content-Type: application/jsonRequest Body:
{ "name": "Q4 Sales Analysis", "description": "Quarterly sales performance analysis", "connector_uuids": ["conn_01ABCDEF", "conn_02GHIJKL"], "metadata": { "department": "analytics", "tags": ["sales", "quarterly"] }}Response: 201 Created
{ "uuid": "proj_01ABCDEF", "name": "Q4 Sales Analysis", "description": "Quarterly sales performance analysis", "connector_uuids": ["conn_01ABCDEF", "conn_02GHIJKL"], "metadata": { "department": "analytics", "tags": ["sales", "quarterly"] }, "created_by": "user_01ABCDEF", "created_at": "2025-01-15T10:00:00Z", "updated_at": "2025-01-15T10:00:00Z", "last_executed_at": null, "status": "draft"}Permission Required: project:create on organization
Error Responses:
// 400 Bad Request - Invalid input{ "error": "validation_error", "message": "Project name is required", "field": "name"}
// 403 Forbidden - No permission to create projects{ "error": "forbidden", "message": "Insufficient permissions to create projects"}List Projects
Section titled “List Projects”Retrieve all projects accessible to the authenticated user with pagination.
GET /api/projectsQuery Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number for pagination |
limit | integer | 20 | Number of results per page (max 100) |
sort | string | created_at | Sort field: created_at, updated_at, name |
order | string | desc | Sort order: asc or desc |
status | string | - | Filter by status: draft, active, archived |
search | string | - | Search in name and description |
Example Request:
curl "https://api.querri.com/api/projects?page=1&limit=10&sort=updated_at&order=desc" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response: 200 OK
{ "data": [ { "uuid": "proj_01ABCDEF", "name": "Q4 Sales Analysis", "description": "Quarterly sales performance analysis", "connector_uuids": ["conn_01ABCDEF"], "created_by": "user_01ABCDEF", "created_at": "2025-01-15T10:00:00Z", "updated_at": "2025-01-15T14:30:00Z", "last_executed_at": "2025-01-15T14:25:00Z", "status": "active", "step_count": 5, "permissions": { "can_edit": true, "can_delete": true, "can_share": true, "role": "owner" } } ], "pagination": { "page": 1, "limit": 10, "total": 42, "total_pages": 5, "has_next": true, "has_prev": false }}Permission Required: User must have at least viewer access to each project returned.
Get Project
Section titled “Get Project”Retrieve a single project by UUID.
GET /api/projects/{uuid}Path Parameters:
| Parameter | Type | Description |
|---|---|---|
uuid | string | Project UUID |
Example Request:
curl "https://api.querri.com/api/projects/proj_01ABCDEF" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response: 200 OK
{ "uuid": "proj_01ABCDEF", "name": "Q4 Sales Analysis", "description": "Quarterly sales performance analysis", "connector_uuids": ["conn_01ABCDEF", "conn_02GHIJKL"], "metadata": { "department": "analytics", "tags": ["sales", "quarterly"] }, "created_by": "user_01ABCDEF", "created_at": "2025-01-15T10:00:00Z", "updated_at": "2025-01-15T14:30:00Z", "last_executed_at": "2025-01-15T14:25:00Z", "status": "active", "steps": [ { "step_id": "step_01ABCDEF", "name": "Extract sales data", "type": "sql_query", "order": 1, "status": "completed" } ], "permissions": { "can_edit": true, "can_delete": true, "can_share": true, "role": "owner" }}Error Responses:
// 404 Not Found{ "error": "not_found", "message": "Project not found"}
// 403 Forbidden{ "error": "forbidden", "message": "Insufficient permissions to view this project"}Permission Required: project:read on the specific project.
Update Project
Section titled “Update Project”Update an existing project’s properties.
PUT /api/projects/{uuid}Headers:
Authorization: Bearer {JWT_TOKEN}Content-Type: application/jsonRequest Body:
{ "name": "Q4 2024 Sales Analysis", "description": "Updated quarterly analysis with new metrics", "connector_uuids": ["conn_01ABCDEF", "conn_03MNOPQR"], "metadata": { "department": "analytics", "tags": ["sales", "quarterly", "2024"] }, "status": "active"}Response: 200 OK
{ "uuid": "proj_01ABCDEF", "name": "Q4 2024 Sales Analysis", "description": "Updated quarterly analysis with new metrics", "connector_uuids": ["conn_01ABCDEF", "conn_03MNOPQR"], "metadata": { "department": "analytics", "tags": ["sales", "quarterly", "2024"] }, "updated_at": "2025-01-15T15:00:00Z", "status": "active"}Permission Required: project:edit on the specific project.
Error Responses:
// 409 Conflict - Project is currently executing{ "error": "conflict", "message": "Cannot update project while execution is in progress"}Delete Project
Section titled “Delete Project”Delete a project and all associated steps and data.
DELETE /api/projects/{uuid}Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
hard_delete | boolean | false | Permanently delete (true) or soft delete (false) |
Example Request:
curl -X DELETE "https://api.querri.com/api/projects/proj_01ABCDEF" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response: 204 No Content
Permission Required: project:delete on the specific project (typically owner only).
Error Responses:
// 409 Conflict - Project has active executions{ "error": "conflict", "message": "Cannot delete project with active executions"}Execute Project
Section titled “Execute Project”Execute all steps in a project sequentially.
POST /api/projects/{uuid}/executeHeaders:
Authorization: Bearer {JWT_TOKEN}Content-Type: application/jsonRequest Body:
{ "parameters": { "start_date": "2024-10-01", "end_date": "2024-12-31" }, "mode": "async", "notify_on_completion": true}Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
parameters | object | No | Runtime parameters passed to steps |
mode | string | No | async (default) or sync |
notify_on_completion | boolean | No | Send notification when complete (default: false) |
Response: 202 Accepted (async mode)
{ "execution_id": "exec_01ABCDEF", "project_uuid": "proj_01ABCDEF", "status": "running", "started_at": "2025-01-15T15:30:00Z", "steps": [ { "step_id": "step_01ABCDEF", "name": "Extract sales data", "status": "running", "started_at": "2025-01-15T15:30:00Z" } ], "progress": { "completed_steps": 0, "total_steps": 5, "percentage": 0 }}Response: 200 OK (sync mode)
{ "execution_id": "exec_01ABCDEF", "project_uuid": "proj_01ABCDEF", "status": "completed", "started_at": "2025-01-15T15:30:00Z", "completed_at": "2025-01-15T15:35:00Z", "duration_seconds": 300, "steps": [ { "step_id": "step_01ABCDEF", "name": "Extract sales data", "status": "completed", "started_at": "2025-01-15T15:30:00Z", "completed_at": "2025-01-15T15:32:00Z", "rows_processed": 15000 } ], "results": { "total_rows": 15000, "output_files": ["s3://bucket/results/exec_01ABCDEF/final.parquet"] }}Permission Required: project:execute on the specific project.
Error Responses:
// 409 Conflict - Project already executing{ "error": "conflict", "message": "Project is already executing", "execution_id": "exec_01EXISTING"}
// 400 Bad Request - Missing required parameters{ "error": "validation_error", "message": "Missing required parameter: start_date", "field": "parameters.start_date"}Project Execution Lifecycle
Section titled “Project Execution Lifecycle”Projects follow this execution lifecycle:
- Draft - Newly created, not yet executed
- Running - Execution in progress
- Completed - All steps executed successfully
- Failed - One or more steps failed
- Cancelled - User cancelled execution
- Active - Has been executed at least once
- Archived - Soft deleted or archived
Monitoring Execution Status
Section titled “Monitoring Execution Status”Poll the project endpoint to monitor execution status:
# Check execution statuscurl "https://api.querri.com/api/projects/proj_01ABCDEF/executions/exec_01ABCDEF" \ -H "Authorization: Bearer {JWT_TOKEN}"Or use webhooks for real-time notifications. See Webhooks API.
Common Use Cases
Section titled “Common Use Cases”Creating and Running a Project
Section titled “Creating and Running a Project”# 1. Create projectPROJECT_UUID=$(curl -X POST https://api.querri.com/api/projects \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"name": "Sales Analysis", "connector_uuids": ["conn_01ABCDEF"]}' \ | jq -r '.uuid')
# 2. Add steps (see Steps API)# ...
# 3. Execute projectcurl -X POST "https://api.querri.com/api/projects/${PROJECT_UUID}/execute" \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"mode": "async", "notify_on_completion": true}'Filtering Projects by Status
Section titled “Filtering Projects by Status”# Get all active projectscurl "https://api.querri.com/api/projects?status=active&limit=50" \ -H "Authorization: Bearer ${JWT_TOKEN}"Searching Projects
Section titled “Searching Projects”# Search for sales-related projectscurl "https://api.querri.com/api/projects?search=sales&limit=20" \ -H "Authorization: Bearer ${JWT_TOKEN}"HTTP Status Codes
Section titled “HTTP Status Codes”| Code | Description |
|---|---|
| 200 | Success (GET, PUT) |
| 201 | Created (POST) |
| 202 | Accepted (async execution started) |
| 204 | No Content (DELETE) |
| 400 | Bad Request (validation errors) |
| 401 | Unauthorized (missing/invalid token) |
| 403 | Forbidden (insufficient permissions) |
| 404 | Not Found (project doesn’t exist) |
| 409 | Conflict (resource state conflict) |
| 429 | Too Many Requests (rate limited) |
| 500 | Internal Server Error |