API Endpoints Reference¶
This document provides a comprehensive reference of all available API endpoints in the ASU APGAP backend.
Base URL: /api/
Authentication: All endpoints require authentication unless otherwise noted. Use JWT tokens obtained from the authentication endpoints.
Authentication¶
Base Path: /authentication/
POST /authentication/login/
Login with email/password credentials.
Request:
Response:
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1...",
"user": {
"pk": 1,
"email": "user@example.com"
}
}
POST /authentication/google/login/
Login with Google OAuth code.
Request:
POST /authentication/token/refresh/
Refresh access token.
Request:
Response:
POST /authentication/token/verify/
Verify token validity.
Request:
Users¶
Base Path: /api/users/
GET /api/users/
List all users.
Response:
[
{
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"is_platform_admin": false,
"is_data_analyst": false,
"is_active": true,
"organization": {
"id": 1,
"display_name": "Arizona State University"
}
}
]
POST /api/users/
Create a new user.
Request:
{
"email": "newuser@example.com",
"first_name": "Jane",
"last_name": "Smith",
"organization": 1,
"is_platform_admin": false,
"is_data_analyst": false,
"lab": 1,
"is_lab_admin": false,
"project": 1
}
GET /api/users/{id}/
Retrieve user details with permissions and memberships.
Response:
{
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"is_platform_admin": false,
"is_data_analyst": false,
"is_active": true,
"is_azdhs_user": false,
"organization": {
"id": 1,
"display_name": "Arizona State University"
},
"permissions": {
"groups": ["Lab Director"],
"permissions": ["labs.view_lab", "labs.change_lab"]
},
"lab_memberships": [
{
"id": 1,
"display_name": "Genomics Lab",
"role": "Lab Director",
"projects": [
{
"id": 1,
"display_name": "COVID-19 Sequencing",
"role": "Bioinformatics User"
}
]
}
],
"project_memberships": [
{
"id": 1,
"display_name": "COVID-19 Sequencing",
"role": "Bioinformatics User"
}
]
}
PATCH /api/users/{id}/
Update user.
Request:
DELETE /api/users/{id}/
Soft delete (deactivate) user.
GET /api/users/me/
Get current authenticated user's details.
POST /api/users/{id}/reactivate/
Reactivate a deactivated user.
Organizations¶
Base Path: /api/organizations/
GET /api/organizations/
List all organizations.
Response:
[
{
"id": 1,
"display_name": "Arizona State University",
"active": true,
"default_approve_analytical_dataset_requests": false
}
]
POST /api/organizations/
Create a new organization.
Request:
GET /api/organizations/{id}/
Retrieve organization details.
PATCH /api/organizations/{id}/
Update organization settings.
Request:
DELETE /api/organizations/{id}/
Soft delete organization (sets active=false). Fails if organization has users.
Labs¶
Base Path: /api/labs/
GET /api/labs/
List labs accessible to user.
Response:
[
{
"id": 1,
"display_name": "Genomics Lab",
"description": "Main genomics research lab",
"project_id": "gcp-project-123",
"organization": {
"id": 1,
"display_name": "Arizona State University"
},
"projects": [
{
"id": 1,
"display_name": "COVID-19 Sequencing",
"status": "ACTIVE"
}
]
}
]
POST /api/labs/
Create a new lab.
Request:
{
"display_name": "New Lab",
"description": "Lab description",
"organization": 1,
"lab_director_id": 1
}
GET /api/labs/{id}/members/
Get all lab members.
Response:
{
"lab_users": [
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": "Lab Director",
"is_lab_admin": true,
"organization": { "id": 1, "display_name": "ASU" }
}
],
"project_users": [
{
"id": 1,
"user_id": 2,
"user_name": "Jane Smith",
"user_email": "jane@example.com",
"project_id": 1,
"project_name": "COVID-19 Sequencing",
"permission_id": 3,
"permission_name": "Bioinformatics User"
}
]
}
POST /api/labs/{id}/assign-user/
Assign a user to the lab.
Request:
POST /api/labs/{id}/remove-user/
Remove a user from the lab.
Request:
Projects¶
Base Path: /api/projects/
GET /api/projects/
List projects accessible to user.
Query Parameters:
lab- Filter by lab IDstatus- Filter by status (ACTIVE, ARCHIVED)
Response:
[
{
"id": 1,
"display_name": "COVID-19 Sequencing",
"lab": 1,
"program": null,
"active": true,
"status": "ACTIVE",
"description": "Project description",
"gcs_bucket": "project-bucket-123",
"output_bucket": "gs://output-bucket",
"opt_out_of_seqera": false,
"build_status": "SUCCESS"
}
]
POST /api/projects/
Create a new project.
Request:
{
"display_name": "New Project",
"lab": 1,
"description": "Project description",
"opt_out_of_seqera": false
}
GET /api/projects/{id}/resource-detail/
Get detailed project information.
Response:
{
"id": 1,
"display_name": "COVID-19 Sequencing",
"description": "Project description",
"opt_out_of_seqera": false,
"seqera_launchpad_url": "https://tower.nf/...",
"vertex_notebook_uri": "https://notebooks.cloud.google.com/...",
"output_bucket": "gs://output-bucket",
"project_id": "gcp-project-id",
"project_users": [...],
"lab_directors": [...]
}
POST /api/projects/{id}/archive/
Archive a project (Lab Director only).
POST /api/projects/{id}/hard-delete/
Permanently delete a project (Platform Admin only).
Request:
Project Users
Base Path: /api/project-users/
POST /api/project-users/
Add user to project.
Request:
Response:
{
"id": 1,
"user": {
"id": 2,
"email": "jane@example.com",
"name": "Jane Smith",
"organization": "ASU"
},
"project": {
"id": 1,
"display_name": "COVID-19 Sequencing"
},
"permission_group": {
"id": 3,
"name": "Bioinformatics User"
}
}
PATCH /api/project-users/{id}/
Update project user role.
Request:
Files¶
Base Path: /api/files/
GET /api/files/
List files with optional pagination.
Query Parameters:
lab- Filter by lab IDstatus- Filter by status (DRAFT, PROCESSING, PRIMARY, ARCHIVED)created_by- Filter by creator IDpagination- Enable pagination (true)page,page_size- Pagination controlssearch- Search in gcs_file_path
Response:
[
{
"id": 1,
"lab": 1,
"lab_name": "Genomics Lab",
"gcs_file_path": "lab-1/sample.fastq",
"file_type": "fastq",
"file_size": 1048576,
"status": "PRIMARY",
"description": null,
"created_by": 1,
"created_by_name": "John Doe",
"created_at": "2024-01-15T10:30:00Z",
"source_type": 1,
"source_type_name": "Illumina",
"batch_upload_id": null,
"batch_upload_name": null,
"copied_to_datasets": []
}
]
POST /api/files/
Create file record or upload file.
Request (upload with file):
Request (metadata only):
GET /api/files/{id}/
Retrieve file details.
Response:
{
"id": 1,
"lab": { "id": 1, "display_name": "Genomics Lab", ... },
"gcs_file_path": "lab-1/sample.fastq",
"gcs_url": "gs://bucket/lab-1/sample.fastq",
"file_type": "fastq",
"file_size": 1048576,
"status": "PRIMARY",
"description": null,
"created_by": 1,
"created_by_email": "john@example.com",
"created_by_name": "John Doe",
"meets_retention_requirement": true,
"metadata_tags": [
{ "key": "sample_id", "value": "S001", "data_type": "TEXT" }
],
"copied_to_datasets": []
}
DELETE /api/files/{id}/
Delete file (requires justification).
Request:
POST /api/files/{id}/associate-metadata/
Set metadata tags for file (replaces existing).
Request:
[
{ "key": "sample_id", "value": "S001", "source_type": 1 },
{ "key": "platforms", "value": ["illumina", "pacbio"], "source_type": 1 }
]
Response:
{
"file_id": 1,
"metadata_set": [
{
"key": "sample_id",
"value": "S001",
"key_created": false,
"value_created": false
}
],
"added": 2,
"removed": 1,
"kept": 0,
"total": 2
}
GET /api/files/{id}/metadata-tags/
Get all metadata tags for file.
Response:
{
"file_id": 1,
"metadata_tags": [
{
"key": "sample_id",
"value": "S001",
"data_type": "TEXT",
"source_type": 1,
"source_type_name": "Illumina",
"is_required": true,
"sort_order": 1
}
],
"count": 1
}
POST /api/files/{id}/set-primary/
Promote file to PRIMARY status.
Uploads¶
Base Path: /api/uploads/
GUI Uploads
POST /api/uploads/
Create GUI upload (returns signed URL).
Request:
{
"filename": "sample.fastq",
"content_type": "application/octet-stream",
"lab": 1,
"time_to_live": 3600,
"file_size": 1048576
}
Response:
{
"id": 1,
"filename": "sample.fastq",
"content_type": "application/octet-stream",
"lab": 1,
"time_to_live": 3600,
"file_size": 1048576,
"upload_url": "https://storage.googleapis.com/...",
"ingest_uuid": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2024-01-15T10:30:00Z",
"file": 1,
"status": "PENDING"
}
Batch Uploads
GET /api/uploads/batch-uploads/
List batch uploads.
Response:
[
{
"id": 1,
"user": "john@example.com",
"lab": "Genomics Lab",
"ingest_bucket": "batch-upload-lab1-20240115-abc123",
"kind": "FASTQ",
"time_to_live": 86400,
"description": "Batch upload for sequencing data",
"created_at": "2024-01-15T10:30:00Z",
"expires_at": "2024-01-16T10:30:00Z",
"is_expired": false,
"file_count": 5
}
]
POST /api/uploads/batch-uploads/
Create batch upload.
Request:
{
"lab": 1,
"kind": "FASTQ",
"time_to_live": 86400,
"description": "Batch upload for sequencing data"
}
Response:
{
"id": 1,
"lab": 1,
"ingest_bucket": "batch-upload-lab1-20240115-abc123",
"kind": "FASTQ",
"time_to_live": 86400,
"description": "Batch upload for sequencing data"
}
GET /api/uploads/batch-uploads/{id}/download_service_account_key/
Download service account keyfile.
Query Parameters:
as_file- Return as downloadable file (true) or JSON response
Datasets (Data Catalog)¶
Base Path: /api/datasets/
GET /api/datasets/
List searchable datasets.
Query Parameters:
type- Filter by type (GUI, BATCH)owning_project- Filter by owning project IDassigned_projects- Filter by assigned project IDsmetadata_tags- Filter by metadata tag IDsmetadata_tag_match_partial-truefor OR,falsefor AND (default)search- Search in display_namepagination,page,page_size- Pagination controls
Response:
[
{
"id": 1,
"display_name": "COVID Samples Dataset",
"description": "Dataset description",
"type": "GUI",
"searchable": true,
"owning_project": { "id": 1, "display_name": "COVID-19 Sequencing" },
"assigned_projects": [{ "id": 2, "display_name": "Analysis Project" }],
"file_count": 50,
"total_file_size": 52428800,
"metadata_tags": [
{
"id": 1,
"metadata_tag": { "id": 1, "key": "organism", "value": "SARS-CoV-2" }
}
]
}
]
POST /api/datasets/
Create a new dataset.
Request:
{
"owning_project": 1,
"display_name": "New Dataset",
"description": "Dataset description",
"type": "GUI",
"searchable": true,
"metadata_tags": [1, 2, 3]
}
POST /api/datasets/{id}/request-access/
Request access to dataset for a project.
Request:
Analytical Datasets¶
Base Path: /api/analytical-datasets/
GET /api/analytical-datasets/
List analytical datasets.
Response:
[
{
"id": 1,
"name": "Analysis Dataset 1",
"date": "2024-01-15T10:30:00Z",
"status": "PENDING",
"gcs_bucket": "analytical-dataset-bucket",
"project": 1,
"lab_name": "Genomics Lab",
"project_name": "COVID-19 Sequencing",
"created_by": 1,
"created_by_email": "john@example.com",
"created_by_name": "John Doe",
"file_count": 10
}
]
POST /api/analytical-datasets/
Create analytical dataset.
Request:
GET /api/analytical-datasets/{id}/
Retrieve analytical dataset with files.
Response:
{
"id": 1,
"name": "Analysis Dataset 1",
"description": "Dataset description",
"gcs_bucket": "analytical-dataset-bucket",
"lab": 1,
"lab_name": "Genomics Lab",
"project": 1,
"project_name": "COVID-19 Sequencing",
"email": "john@example.com",
"created_by": "John Doe",
"created_by_name": "John Doe",
"file_count": 10,
"files": [
{
"id": 1,
"gcs_file_path": "file.fastq",
"file_type": "fastq",
"file_size": 1048576,
"status": "PRIMARY",
"original_file_id": 5,
"original_file_path": "lab-1/original.fastq",
"lab_name": "Genomics Lab",
"metadata_tags": [...]
}
],
"access_requests": [
{
"id": 1,
"name": "sample.fastq",
"lab_name": "Other Lab",
"status": "PENDING",
"denied_by": null,
"denial_reason": null
}
]
}
POST /api/analytical-datasets/{id}/copy_file/
Copy file to dataset.
Request:
Response (if auto-approved):
{
"id": 10,
"gcs_file_path": "copied-file.fastq",
"file_type": "fastq",
"file_size": 1048576,
"status": "PRIMARY",
"original_file_id": 5,
"metadata_tags": [...]
}
Response (if pending approval):
{
"message": "Access request has been created and is pending approval.",
"access_request_id": 1,
"status": "PENDING"
}
POST /api/analytical-datasets/{id}/approve/
Approve pending access requests (Lab Director).
Response:
POST /api/analytical-datasets/{id}/deny/
Deny pending access requests (Lab Director).
Request:
Response:
POST /api/analytical-datasets/{id}/request_access_to_files/
Request access to multiple files.
Request:
Response:
{
"created": [{ "id": 1, "file_id": 1, "status": "PENDING" }],
"existing": [{ "id": 2, "file_id": 2, "status": "APPROVED" }]
}
Access Requests¶
Base Path: /api/access-requests/
GET /api/access-requests/
List access requests.
Response:
[
{
"id": 1,
"user": 2,
"user_email": "jane@example.com",
"user_name": "Jane Smith",
"analytical_dataset": 1,
"analytical_dataset_name": "Analysis Dataset 1",
"file": 5,
"file_name": "sample.fastq",
"status": "PENDING",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
]
POST /api/access-requests/
Create access request.
Request:
POST /api/access-requests/{id}/approve/
Approve access request.
POST /api/access-requests/{id}/reject/
Reject access request.
GET /api/access-requests/my-requests/
Get current user's access requests.
GET /api/access-requests/pending-approvals/
Get pending requests for approval.
Notifications¶
Base Path: /api/notifications/
GET /api/notifications/
List notifications for current user.
Response:
{
"count": 10,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"title": "Access Request Approved",
"details": "Your access request has been approved",
"status": "info",
"notification": "ACCESS_REQUEST_APPROVED",
"created_at": "2024-01-15T10:30:00Z"
}
]
}
GET /api/notifications/preferences/
Get notification preferences.
Response:
PUT /api/notifications/preferences/
Update notification preferences (batch).
Request:
Metadata Tags¶
Base Path: /api/metadata-tags/
GET /api/metadata-tags/
List metadata tags.
Query Parameters:
key- Filter by key namevalue- Filter by value name
Response:
[
{
"id": 1,
"key": { "id": 1, "name": "organism", "data_type": "TEXT" },
"value": { "id": 1, "name": "SARS-CoV-2" }
}
]
Metadata Requirements¶
Base Path: /api/metadata-requirements/
Source Types
GET /api/metadata-requirements/source-types/
List source types.
Response:
POST /api/metadata-requirements/source-types/
Create source type.
Request:
Templates
GET /api/metadata-requirements/templates/
List metadata templates.
Query Parameters:
source_type- Filter by source type IDis_required- Filter by required statusis_core- Filter by core status
Response:
[
{
"id": 1,
"key": { "id": 1, "name": "sample_id", "data_type": "TEXT" },
"source_type": { "id": 1, "name": "Illumina" },
"is_required": true,
"is_core": true,
"sort_order": 1,
"template_options": [{ "id": 1, "value": { "id": 1, "name": "option1" } }]
}
]
POST /api/metadata-requirements/templates/
Create template.
Request:
{
"key": "new_field",
"source_type": 1,
"is_required": false,
"is_core": false,
"sort_order": 10,
"data_type": "SELECT",
"options": ["option1", "option2"]
}
GET /api/metadata-requirements/templates/download_csv/
Download CSV template.
Query Parameters:
source_type- Source type IDinclude_info_row- Include requirement info (true/false)
POST /api/metadata-requirements/templates/upload_csv/
Upload CSV with metadata.
Request:
Response:
{
"success": true,
"success_count": 10,
"error_count": 0,
"processed_files": ["file1.fastq", "file2.fastq"],
"message": "Successfully processed 10 files",
"errors": [],
"warnings": []
}
Domain Whitelist¶
Base Path: /api/domain-whitelist/
GET /api/domain-whitelist/
List whitelisted domains.
Response:
[
{
"id": 1,
"domain": "asu.edu",
"description": "Arizona State University",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
]
POST /api/domain-whitelist/
Add domain to whitelist.
Request:
Deletions¶
Base Path: /api/deletions/
Archive Requests
GET /api/deletions/archive-requests/
List archive requests.
Response:
[
{
"id": 1,
"status": "PENDING",
"justification": "Data no longer needed",
"external_storage_location": "https://archive.example.com/file123",
"retention_requirement_met": true,
"requested_by": { "id": 1, "email": "john@example.com" },
"reviewed_by": null,
"reviewed_at": null,
"created_at": "2024-01-15T10:30:00Z"
}
]
POST /api/deletions/archive-requests/
Create archive request.
Request:
{
"content_type": 15,
"object_id": 1,
"justification": "Data no longer needed for research",
"external_storage_location": "https://archive.example.com/file123"
}
POST /api/deletions/archive-requests/{id}/approve/
Approve archive request.
POST /api/deletions/archive-requests/{id}/deny/
Deny archive request.
Request:
API Documentation¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/schema/ |
OpenAPI schema (JSON/YAML) |
| GET | /api/docs/ |
Swagger UI documentation |
Common Response Codes¶
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful delete) |
| 207 | Multi-Status (partial success) |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized (not authenticated) |
| 403 | Forbidden (no permission) |
| 404 | Not Found |
| 500 | Internal Server Error |
Pagination¶
Many list endpoints support optional pagination:
- Add
?pagination=trueto enable pagination - Use
?page=Nto specify page number - Use
?page_size=Nto specify items per page (max 100)
When pagination is enabled, responses include:
{
"count": 100,
"next": "http://api/endpoint/?pagination=true&page=2",
"previous": null,
"results": [...]
}
Filtering and Search¶
Most list endpoints support:
- Filtering: Use query parameters matching field names (e.g.,
?status=PENDING) - Search: Use
?search=termto search across multiple fields - Ordering: Use
?ordering=fieldor?ordering=-fieldfor descending
Error Responses¶
Error responses follow this format:
Field validation errors: