Skip to content

Projects API

The Projects API allows you to create, manage, and execute data analysis projects. Projects contain steps, connectors, and execution history.

All endpoints are prefixed with /api and routed through Traefik reverse proxy:

https://api.querri.com/api

All Projects API endpoints require JWT authentication. See Authentication for details.

Create a new project in your organization.

POST /api/projects

Headers:

Authorization: Bearer {JWT_TOKEN}
Content-Type: application/json

Request 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"
}

Retrieve all projects accessible to the authenticated user with pagination.

GET /api/projects

Query Parameters:

ParameterTypeDefaultDescription
pageinteger1Page number for pagination
limitinteger20Number of results per page (max 100)
sortstringcreated_atSort field: created_at, updated_at, name
orderstringdescSort order: asc or desc
statusstring-Filter by status: draft, active, archived
searchstring-Search in name and description

Example Request:

Terminal window
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.


Retrieve a single project by UUID.

GET /api/projects/{uuid}

Path Parameters:

ParameterTypeDescription
uuidstringProject UUID

Example Request:

Terminal window
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 an existing project’s properties.

PUT /api/projects/{uuid}

Headers:

Authorization: Bearer {JWT_TOKEN}
Content-Type: application/json

Request 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 a project and all associated steps and data.

DELETE /api/projects/{uuid}

Query Parameters:

ParameterTypeDefaultDescription
hard_deletebooleanfalsePermanently delete (true) or soft delete (false)

Example Request:

Terminal window
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 all steps in a project sequentially.

POST /api/projects/{uuid}/execute

Headers:

Authorization: Bearer {JWT_TOKEN}
Content-Type: application/json

Request Body:

{
"parameters": {
"start_date": "2024-10-01",
"end_date": "2024-12-31"
},
"mode": "async",
"notify_on_completion": true
}

Parameters:

FieldTypeRequiredDescription
parametersobjectNoRuntime parameters passed to steps
modestringNoasync (default) or sync
notify_on_completionbooleanNoSend 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"
}

Projects follow this execution lifecycle:

  1. Draft - Newly created, not yet executed
  2. Running - Execution in progress
  3. Completed - All steps executed successfully
  4. Failed - One or more steps failed
  5. Cancelled - User cancelled execution
  6. Active - Has been executed at least once
  7. Archived - Soft deleted or archived

Poll the project endpoint to monitor execution status:

Terminal window
# Check execution status
curl "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.

Terminal window
# 1. Create project
PROJECT_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 project
curl -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}'
Terminal window
# Get all active projects
curl "https://api.querri.com/api/projects?status=active&limit=50" \
-H "Authorization: Bearer ${JWT_TOKEN}"
Terminal window
# Search for sales-related projects
curl "https://api.querri.com/api/projects?search=sales&limit=20" \
-H "Authorization: Bearer ${JWT_TOKEN}"
CodeDescription
200Success (GET, PUT)
201Created (POST)
202Accepted (async execution started)
204No Content (DELETE)
400Bad Request (validation errors)
401Unauthorized (missing/invalid token)
403Forbidden (insufficient permissions)
404Not Found (project doesn’t exist)
409Conflict (resource state conflict)
429Too Many Requests (rate limited)
500Internal Server Error