{ "openapi": "3.0.3", "info": { "title": "Goa GEL - Blockchain Document Verification Platform API", "description": "## Overview\nREST API for the Government of Goa's Blockchain-based Document Verification Platform (GEL).\nThis platform enables multi-department approval workflows for various licenses and permits,\nwith blockchain-backed verification using Hyperledger Besu and ERC-721 Soulbound NFTs.\n\n## Authentication\n- **Department APIs**: Use `X-API-Key` and `X-Department-Code` headers\n- **Applicant APIs**: Use Bearer token from DigiLocker authentication (mock for POC)\n- **Admin APIs**: Use Bearer token with admin role\n\n## Blockchain Integration\nAll critical operations (request creation, approvals, document updates) are recorded on-chain.\nResponse includes `transactionHash` for blockchain verification.\n\n## Webhooks\nDepartments can register webhooks to receive real-time notifications for:\n- `APPROVAL_REQUIRED` - New request pending approval\n- `DOCUMENT_UPDATED` - Applicant updated a document\n- `REQUEST_APPROVED` - Request fully approved\n- `REQUEST_REJECTED` - Request rejected\n", "version": "1.0.0", "contact": { "name": "Goa GEL Platform Support", "email": "support@goagel.gov.in" }, "license": { "name": "Government of Goa", "url": "https://www.goa.gov.in" } }, "servers": [ { "url": "https://api.goagel.gov.in/api/v1", "description": "Production server" }, { "url": "https://staging-api.goagel.gov.in/api/v1", "description": "Staging server" }, { "url": "http://localhost:3001/api/v1", "description": "Local development" } ], "tags": [ { "name": "Requests", "description": "License request operations" }, { "name": "Documents", "description": "Document upload and retrieval" }, { "name": "Approvals", "description": "Department approval actions" }, { "name": "Departments", "description": "Department management" }, { "name": "Workflows", "description": "Workflow configuration" }, { "name": "Webhooks", "description": "Webhook management" }, { "name": "Admin", "description": "Platform administration" }, { "name": "Verification", "description": "Public verification endpoints" } ], "paths": { "/requests": { "post": { "tags": [ "Requests" ], "summary": "Create new license request", "description": "Creates a new license request and mints a draft NFT on the blockchain.\nThe request starts in DRAFT status until submitted.\n", "operationId": "createRequest", "security": [ { "BearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateRequestInput" }, "example": { "applicantId": "DL-GOA-123456789", "requestType": "RESORT_LICENSE", "metadata": { "resortName": "Paradise Beach Resort", "location": "Calangute, North Goa", "plotArea": 5000, "builtUpArea": 3500, "numberOfRooms": 50 } } } } }, "responses": { "201": { "description": "Request created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RequestResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" } } }, "get": { "tags": [ "Requests" ], "summary": "List requests", "description": "Get list of requests with optional filters", "operationId": "listRequests", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "name": "status", "in": "query", "schema": { "$ref": "#/components/schemas/RequestStatus" } }, { "name": "requestType", "in": "query", "schema": { "type": "string", "example": "RESORT_LICENSE" } }, { "name": "applicantId", "in": "query", "schema": { "type": "string" } }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } }, { "name": "sortBy", "in": "query", "schema": { "type": "string", "enum": [ "createdAt", "updatedAt", "status" ], "default": "createdAt" } }, { "name": "sortOrder", "in": "query", "schema": { "type": "string", "enum": [ "asc", "desc" ], "default": "desc" } } ], "responses": { "200": { "description": "List of requests", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RequestListResponse" } } } } } } }, "/requests/pending": { "get": { "tags": [ "Requests" ], "summary": "Get requests pending for department", "description": "Returns all requests that are pending approval from the specified department", "operationId": "getPendingRequests", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "name": "department", "in": "query", "required": true, "schema": { "type": "string" }, "example": "FIRE_DEPT" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20 } } ], "responses": { "200": { "description": "List of pending requests", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RequestListResponse" } } } } } } }, "/requests/{requestId}": { "get": { "tags": [ "Requests" ], "summary": "Get request details", "description": "Returns complete request details including documents, approvals,\ncurrent workflow stage, and full timeline of events.\n", "operationId": "getRequest", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "responses": { "200": { "description": "Request details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RequestDetailResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/requests/{requestId}/submit": { "post": { "tags": [ "Requests" ], "summary": "Submit request for approval", "description": "Submits the request for departmental approval workflow.\nValidates that all required documents are uploaded before submission.\nRecords submission on blockchain and notifies relevant departments.\n", "operationId": "submitRequest", "security": [ { "BearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "responses": { "200": { "description": "Request submitted successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "requestId": { "type": "string", "format": "uuid" }, "status": { "type": "string", "example": "SUBMITTED" }, "currentStage": { "$ref": "#/components/schemas/WorkflowStage" }, "pendingDepartments": { "type": "array", "items": { "type": "string" }, "example": [ "FIRE_DEPT", "TOURISM_DEPT" ] }, "transactionHash": { "type": "string", "example": "0x1234567890abcdef..." } } } } } }, "400": { "description": "Missing required documents", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "code": "MISSING_DOCUMENTS", "message": "Required documents not uploaded", "details": { "missingDocuments": [ "FIRE_SAFETY_CERTIFICATE", "BUILDING_PLAN" ] } } } } } } } }, "/requests/{requestId}/cancel": { "post": { "tags": [ "Requests" ], "summary": "Cancel request", "description": "Cancels a request that is in DRAFT or PENDING_RESUBMISSION status", "operationId": "cancelRequest", "security": [ { "BearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "reason": { "type": "string", "example": "No longer needed" } } } } } }, "responses": { "200": { "description": "Request cancelled", "content": { "application/json": { "schema": { "type": "object", "properties": { "requestId": { "type": "string" }, "status": { "type": "string", "example": "CANCELLED" }, "transactionHash": { "type": "string" } } } } } } } } }, "/requests/{requestId}/timeline": { "get": { "tags": [ "Requests" ], "summary": "Get request timeline", "description": "Returns chronological list of all events for this request", "operationId": "getRequestTimeline", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "responses": { "200": { "description": "Request timeline", "content": { "application/json": { "schema": { "type": "object", "properties": { "requestId": { "type": "string" }, "events": { "type": "array", "items": { "$ref": "#/components/schemas/TimelineEvent" } } } } } } } } } }, "/requests/{requestId}/documents": { "post": { "tags": [ "Documents" ], "summary": "Upload document", "description": "Uploads a document for the request. The document is:\n1. Stored in MinIO with versioning\n2. Hash generated using SHA-256\n3. Hash recorded on blockchain\n4. Linked to the request NFT\n", "operationId": "uploadDocument", "security": [ { "BearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "file", "docType" ], "properties": { "file": { "type": "string", "format": "binary", "description": "Document file (PDF, JPG, PNG)" }, "docType": { "type": "string", "description": "Document type code", "example": "FIRE_SAFETY_CERTIFICATE" }, "description": { "type": "string", "description": "Optional description", "example": "Fire safety certificate from Fire Department" } } } } } }, "responses": { "201": { "description": "Document uploaded successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentResponse" } } } }, "400": { "description": "Invalid file or document type" }, "413": { "description": "File too large (max 10MB)" } } }, "get": { "tags": [ "Documents" ], "summary": "List request documents", "description": "Returns all documents associated with the request", "operationId": "listRequestDocuments", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "responses": { "200": { "description": "List of documents", "content": { "application/json": { "schema": { "type": "object", "properties": { "requestId": { "type": "string" }, "documents": { "type": "array", "items": { "$ref": "#/components/schemas/Document" } } } } } } } } } }, "/documents/{documentId}": { "get": { "tags": [ "Documents" ], "summary": "Get document details", "description": "Returns document metadata and all versions", "operationId": "getDocument", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "name": "documentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Document details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentDetailResponse" } } } } } } }, "/documents/{documentId}/download": { "get": { "tags": [ "Documents" ], "summary": "Download document", "description": "Returns a signed URL for downloading the document", "operationId": "downloadDocument", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "name": "documentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "version", "in": "query", "description": "Specific version to download (defaults to latest)", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Download URL", "content": { "application/json": { "schema": { "type": "object", "properties": { "downloadUrl": { "type": "string", "format": "uri", "description": "Signed URL (expires in 1 hour)" }, "expiresAt": { "type": "string", "format": "date-time" } } } } } } } } }, "/requests/{requestId}/documents/{documentId}": { "put": { "tags": [ "Documents" ], "summary": "Update document (new version)", "description": "Uploads a new version of an existing document.\nThis will:\n1. Create new version in MinIO\n2. Generate new hash\n3. Record new hash on blockchain\n4. Mark affected approvals as \"REVIEW_REQUIRED\"\n5. Notify affected departments via webhook\n", "operationId": "updateDocument", "security": [ { "BearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" }, { "name": "documentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "file" ], "properties": { "file": { "type": "string", "format": "binary" }, "description": { "type": "string" } } } } } }, "responses": { "200": { "description": "Document updated", "content": { "application/json": { "schema": { "type": "object", "properties": { "documentId": { "type": "string" }, "newVersion": { "type": "integer" }, "newHash": { "type": "string" }, "invalidatedApprovals": { "type": "array", "items": { "type": "string" }, "description": "Department codes that need re-review" }, "transactionHash": { "type": "string" } } } } } } } } }, "/requests/{requestId}/approve": { "post": { "tags": [ "Approvals" ], "summary": "Approve request", "description": "Records department approval on the blockchain.\nIf all required approvals for the current stage are complete,\nautomatically advances to the next stage or finalizes the request.\n", "operationId": "approveRequest", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "remarks", "reviewedDocuments" ], "properties": { "remarks": { "type": "string", "example": "All fire safety requirements met" }, "reviewedDocuments": { "type": "array", "items": { "type": "string", "format": "uuid" }, "description": "Document IDs that were reviewed" } } } } } }, "responses": { "200": { "description": "Approval recorded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApprovalResponse" } } } } } } }, "/requests/{requestId}/reject": { "post": { "tags": [ "Approvals" ], "summary": "Reject request", "description": "Records department rejection. This permanently rejects the request.", "operationId": "rejectRequest", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "remarks", "reason" ], "properties": { "remarks": { "type": "string", "example": "Fire safety standards not met" }, "reason": { "type": "string", "enum": [ "SAFETY_VIOLATION", "INCOMPLETE_DOCUMENTS", "POLICY_VIOLATION", "FRAUDULENT_APPLICATION", "OTHER" ] } } } } } }, "responses": { "200": { "description": "Rejection recorded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApprovalResponse" } } } } } } }, "/requests/{requestId}/request-changes": { "post": { "tags": [ "Approvals" ], "summary": "Request changes", "description": "Requests additional information or document updates from the applicant.\nThe request status changes to PENDING_RESUBMISSION.\n", "operationId": "requestChanges", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "remarks" ], "properties": { "remarks": { "type": "string", "example": "Please provide updated fire safety certificate with recent inspection" }, "requiredDocuments": { "type": "array", "items": { "type": "string" }, "description": "Additional document types needed", "example": [ "FIRE_SAFETY_CERTIFICATE", "INSPECTION_REPORT" ] } } } } } }, "responses": { "200": { "description": "Changes requested", "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "example": "CHANGES_REQUESTED" }, "transactionHash": { "type": "string" } } } } } } } } }, "/requests/{requestId}/approvals": { "get": { "tags": [ "Approvals" ], "summary": "Get all approvals for request", "description": "Returns all approval records including historical/invalidated ones", "operationId": "getRequestApprovals", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/RequestId" }, { "name": "includeInvalidated", "in": "query", "schema": { "type": "boolean", "default": false } } ], "responses": { "200": { "description": "List of approvals", "content": { "application/json": { "schema": { "type": "object", "properties": { "requestId": { "type": "string" }, "approvals": { "type": "array", "items": { "$ref": "#/components/schemas/Approval" } } } } } } } } } }, "/departments": { "get": { "tags": [ "Departments" ], "summary": "List all departments", "description": "Returns all registered departments", "operationId": "listDepartments", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "responses": { "200": { "description": "List of departments", "content": { "application/json": { "schema": { "type": "object", "properties": { "departments": { "type": "array", "items": { "$ref": "#/components/schemas/Department" } } } } } } } } }, "post": { "tags": [ "Departments" ], "summary": "Register new department", "description": "Registers a new department and creates blockchain wallet", "operationId": "createDepartment", "security": [ { "AdminAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDepartmentInput" } } } }, "responses": { "201": { "description": "Department created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DepartmentResponse" } } } } } } }, "/departments/{departmentCode}": { "get": { "tags": [ "Departments" ], "summary": "Get department details", "operationId": "getDepartment", "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "name": "departmentCode", "in": "path", "required": true, "schema": { "type": "string" }, "example": "FIRE_DEPT" } ], "responses": { "200": { "description": "Department details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Department" } } } } } }, "patch": { "tags": [ "Departments" ], "summary": "Update department", "operationId": "updateDepartment", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "departmentCode", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string" }, "webhookUrl": { "type": "string", "format": "uri" }, "isActive": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "Department updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Department" } } } } } } }, "/departments/{departmentCode}/regenerate-api-key": { "post": { "tags": [ "Departments" ], "summary": "Regenerate API key", "description": "Generates a new API key for the department (invalidates the old key)", "operationId": "regenerateApiKey", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "departmentCode", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "New API key generated", "content": { "application/json": { "schema": { "type": "object", "properties": { "apiKey": { "type": "string", "description": "New API key (shown only once)" }, "apiSecret": { "type": "string", "description": "New API secret (shown only once)" } } } } } } } } }, "/departments/{departmentCode}/stats": { "get": { "tags": [ "Departments" ], "summary": "Get department statistics", "operationId": "getDepartmentStats", "security": [ { "ApiKeyAuth": [] }, { "AdminAuth": [] } ], "parameters": [ { "name": "departmentCode", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date" } } ], "responses": { "200": { "description": "Department statistics", "content": { "application/json": { "schema": { "type": "object", "properties": { "departmentCode": { "type": "string" }, "period": { "type": "object", "properties": { "start": { "type": "string", "format": "date" }, "end": { "type": "string", "format": "date" } } }, "stats": { "type": "object", "properties": { "totalReceived": { "type": "integer" }, "approved": { "type": "integer" }, "rejected": { "type": "integer" }, "pending": { "type": "integer" }, "avgProcessingTimeDays": { "type": "number" } } } } } } } } } } }, "/workflows": { "get": { "tags": [ "Workflows" ], "summary": "List workflow definitions", "operationId": "listWorkflows", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "isActive", "in": "query", "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "List of workflows", "content": { "application/json": { "schema": { "type": "object", "properties": { "workflows": { "type": "array", "items": { "$ref": "#/components/schemas/Workflow" } } } } } } } } }, "post": { "tags": [ "Workflows" ], "summary": "Create workflow definition", "operationId": "createWorkflow", "security": [ { "AdminAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWorkflowInput" } } } }, "responses": { "201": { "description": "Workflow created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Workflow" } } } } } } }, "/workflows/{workflowId}": { "get": { "tags": [ "Workflows" ], "summary": "Get workflow details", "operationId": "getWorkflow", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "workflowId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Workflow details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Workflow" } } } } } }, "put": { "tags": [ "Workflows" ], "summary": "Update workflow", "description": "Updates a workflow definition. Creates a new version.\nIn-progress requests continue with their original workflow version.\n", "operationId": "updateWorkflow", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "workflowId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWorkflowInput" } } } }, "responses": { "200": { "description": "Workflow updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Workflow" } } } } } }, "delete": { "tags": [ "Workflows" ], "summary": "Deactivate workflow", "description": "Deactivates the workflow. Cannot be used for new requests.", "operationId": "deactivateWorkflow", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "workflowId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Workflow deactivated" } } } }, "/workflows/{workflowId}/validate": { "post": { "tags": [ "Workflows" ], "summary": "Validate workflow definition", "description": "Validates workflow for circular dependencies, missing departments, etc.", "operationId": "validateWorkflow", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "workflowId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Validation result", "content": { "application/json": { "schema": { "type": "object", "properties": { "isValid": { "type": "boolean" }, "errors": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "path": { "type": "string" } } } } } } } } } } } }, "/webhooks": { "get": { "tags": [ "Webhooks" ], "summary": "List registered webhooks", "operationId": "listWebhooks", "security": [ { "ApiKeyAuth": [] }, { "AdminAuth": [] } ], "responses": { "200": { "description": "List of webhooks", "content": { "application/json": { "schema": { "type": "object", "properties": { "webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } } } } } } } } }, "post": { "tags": [ "Webhooks" ], "summary": "Register webhook", "operationId": "createWebhook", "security": [ { "ApiKeyAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookInput" } } } }, "responses": { "201": { "description": "Webhook registered", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Webhook" } } } } } } }, "/webhooks/{webhookId}": { "delete": { "tags": [ "Webhooks" ], "summary": "Delete webhook", "operationId": "deleteWebhook", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "name": "webhookId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Webhook deleted" } } } }, "/webhooks/{webhookId}/test": { "post": { "tags": [ "Webhooks" ], "summary": "Test webhook", "description": "Sends a test payload to the webhook URL", "operationId": "testWebhook", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "name": "webhookId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Test result", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "statusCode": { "type": "integer" }, "responseTime": { "type": "integer", "description": "Response time in ms" } } } } } } } } }, "/webhooks/logs": { "get": { "tags": [ "Webhooks" ], "summary": "Get webhook delivery logs", "operationId": "getWebhookLogs", "security": [ { "ApiKeyAuth": [] }, { "AdminAuth": [] } ], "parameters": [ { "name": "webhookId", "in": "query", "schema": { "type": "string", "format": "uuid" } }, { "name": "status", "in": "query", "schema": { "type": "string", "enum": [ "success", "failed", "pending" ] } }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } } ], "responses": { "200": { "description": "Webhook logs", "content": { "application/json": { "schema": { "type": "object", "properties": { "logs": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookLog" } } } } } } } } } }, "/admin/stats": { "get": { "tags": [ "Admin" ], "summary": "Get platform statistics", "operationId": "getPlatformStats", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date" } } ], "responses": { "200": { "description": "Platform statistics", "content": { "application/json": { "schema": { "type": "object", "properties": { "period": { "type": "object", "properties": { "start": { "type": "string", "format": "date" }, "end": { "type": "string", "format": "date" } } }, "requests": { "type": "object", "properties": { "total": { "type": "integer" }, "byStatus": { "type": "object", "additionalProperties": { "type": "integer" } }, "byType": { "type": "object", "additionalProperties": { "type": "integer" } } } }, "blockchain": { "type": "object", "properties": { "totalTransactions": { "type": "integer" }, "nftsMinted": { "type": "integer" }, "avgGasUsed": { "type": "number" } } }, "performance": { "type": "object", "properties": { "avgProcessingTimeDays": { "type": "number" }, "requestsPerDay": { "type": "number" } } } } } } } } } } }, "/admin/audit-logs": { "get": { "tags": [ "Admin" ], "summary": "Get audit logs", "operationId": "getAuditLogs", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "entityType", "in": "query", "schema": { "type": "string", "enum": [ "REQUEST", "APPROVAL", "DOCUMENT", "DEPARTMENT", "WORKFLOW" ] } }, { "name": "entityId", "in": "query", "schema": { "type": "string", "format": "uuid" } }, { "name": "action", "in": "query", "schema": { "type": "string" } }, { "name": "actorId", "in": "query", "schema": { "type": "string", "format": "uuid" } }, { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date-time" } }, { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date-time" } }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } } ], "responses": { "200": { "description": "Audit logs", "content": { "application/json": { "schema": { "type": "object", "properties": { "logs": { "type": "array", "items": { "$ref": "#/components/schemas/AuditLog" } }, "pagination": { "$ref": "#/components/schemas/Pagination" } } } } } } } } }, "/admin/blockchain/status": { "get": { "tags": [ "Admin" ], "summary": "Get blockchain network status", "operationId": "getBlockchainStatus", "security": [ { "AdminAuth": [] } ], "responses": { "200": { "description": "Blockchain status", "content": { "application/json": { "schema": { "type": "object", "properties": { "network": { "type": "object", "properties": { "chainId": { "type": "integer" }, "networkId": { "type": "integer" }, "consensus": { "type": "string", "example": "QBFT" } } }, "nodes": { "type": "array", "items": { "type": "object", "properties": { "nodeId": { "type": "string" }, "isValidator": { "type": "boolean" }, "isHealthy": { "type": "boolean" }, "peers": { "type": "integer" }, "latestBlock": { "type": "integer" } } } }, "latestBlock": { "type": "object", "properties": { "number": { "type": "integer" }, "hash": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" } } } } } } } } } } }, "/admin/blockchain/transactions": { "get": { "tags": [ "Admin" ], "summary": "Get blockchain transactions", "operationId": "getBlockchainTransactions", "security": [ { "AdminAuth": [] } ], "parameters": [ { "name": "txType", "in": "query", "schema": { "type": "string", "enum": [ "MINT_NFT", "APPROVAL", "DOC_UPDATE", "REJECT", "REVOKE" ] } }, { "name": "status", "in": "query", "schema": { "type": "string", "enum": [ "PENDING", "CONFIRMED", "FAILED" ] } }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } } ], "responses": { "200": { "description": "Blockchain transactions", "content": { "application/json": { "schema": { "type": "object", "properties": { "transactions": { "type": "array", "items": { "$ref": "#/components/schemas/BlockchainTransaction" } }, "pagination": { "$ref": "#/components/schemas/Pagination" } } } } } } } } }, "/verify/{tokenId}": { "get": { "tags": [ "Verification" ], "summary": "Verify license by token ID", "description": "Public endpoint for verifying a license using its NFT token ID.\nNo authentication required.\n", "operationId": "verifyByTokenId", "parameters": [ { "name": "tokenId", "in": "path", "required": true, "schema": { "type": "integer" }, "example": 12345 } ], "responses": { "200": { "description": "Verification result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerificationResponse" } } } }, "404": { "description": "Token not found" } } } }, "/verify/qr/{qrCode}": { "get": { "tags": [ "Verification" ], "summary": "Verify license by QR code", "description": "Public endpoint for verifying a license using QR code data", "operationId": "verifyByQrCode", "parameters": [ { "name": "qrCode", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Verification result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerificationResponse" } } } } } } }, "/verify/document/{hash}": { "get": { "tags": [ "Verification" ], "summary": "Verify document by hash", "description": "Public endpoint for verifying a document using its hash", "operationId": "verifyDocumentByHash", "parameters": [ { "name": "hash", "in": "path", "required": true, "schema": { "type": "string" }, "example": "0x1234567890abcdef..." } ], "responses": { "200": { "description": "Document verification result", "content": { "application/json": { "schema": { "type": "object", "properties": { "isValid": { "type": "boolean" }, "documentId": { "type": "string" }, "requestId": { "type": "string" }, "docType": { "type": "string" }, "version": { "type": "integer" }, "uploadedAt": { "type": "string", "format": "date-time" }, "blockchainRecord": { "type": "object", "properties": { "transactionHash": { "type": "string" }, "blockNumber": { "type": "integer" }, "timestamp": { "type": "string", "format": "date-time" } } } } } } } } } } } }, "components": { "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "JWT token from DigiLocker authentication" }, "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key", "description": "Department API key. Must be used with X-Department-Code header.\n" }, "AdminAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "Admin JWT token" } }, "parameters": { "RequestId": { "name": "requestId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Unique request identifier" } }, "responses": { "BadRequest": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "Unauthorized": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "code": "UNAUTHORIZED", "message": "Invalid or missing authentication" } } } }, "NotFound": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "code": "NOT_FOUND", "message": "Request not found" } } } } }, "schemas": { "CreateRequestInput": { "type": "object", "required": [ "applicantId", "requestType" ], "properties": { "applicantId": { "type": "string", "description": "DigiLocker ID", "example": "DL-GOA-123456789" }, "requestType": { "type": "string", "description": "Type of license/permit", "enum": [ "RESORT_LICENSE", "TRADE_LICENSE", "BUILDING_PERMIT" ], "example": "RESORT_LICENSE" }, "metadata": { "type": "object", "description": "Request-specific data", "additionalProperties": true } } }, "CreateDepartmentInput": { "type": "object", "required": [ "code", "name" ], "properties": { "code": { "type": "string", "pattern": "^[A-Z_]+$", "example": "FIRE_DEPT" }, "name": { "type": "string", "example": "Fire & Emergency Services Department" }, "webhookUrl": { "type": "string", "format": "uri" } } }, "CreateWorkflowInput": { "type": "object", "required": [ "workflowType", "name", "stages" ], "properties": { "workflowType": { "type": "string", "example": "RESORT_LICENSE" }, "name": { "type": "string", "example": "Resort License Approval Workflow" }, "description": { "type": "string" }, "stages": { "type": "array", "items": { "$ref": "#/components/schemas/WorkflowStageInput" } } } }, "WorkflowStageInput": { "type": "object", "required": [ "stageId", "stageName", "stageOrder", "executionType", "requiredApprovals" ], "properties": { "stageId": { "type": "string" }, "stageName": { "type": "string" }, "stageOrder": { "type": "integer" }, "executionType": { "type": "string", "enum": [ "SEQUENTIAL", "PARALLEL" ] }, "requiredApprovals": { "type": "array", "items": { "type": "object", "properties": { "departmentCode": { "type": "string" }, "requiredDocuments": { "type": "array", "items": { "type": "string" } }, "isMandatory": { "type": "boolean" } } } }, "completionCriteria": { "type": "string", "enum": [ "ALL", "ANY", "THRESHOLD" ], "default": "ALL" }, "threshold": { "type": "integer" }, "timeoutDays": { "type": "integer" }, "onTimeout": { "type": "string", "enum": [ "NOTIFY", "ESCALATE", "AUTO_REJECT" ] }, "onRejection": { "type": "string", "enum": [ "FAIL_REQUEST", "RETRY_STAGE", "ESCALATE" ] } } }, "CreateWebhookInput": { "type": "object", "required": [ "url", "events", "secret" ], "properties": { "departmentCode": { "type": "string" }, "url": { "type": "string", "format": "uri" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "APPROVAL_REQUIRED", "DOCUMENT_UPDATED", "REQUEST_APPROVED", "REQUEST_REJECTED", "CHANGES_REQUESTED" ] } }, "secret": { "type": "string", "description": "Secret for HMAC signature verification" } } }, "RequestResponse": { "type": "object", "properties": { "requestId": { "type": "string", "format": "uuid" }, "requestNumber": { "type": "string", "example": "RL-2024-001234" }, "status": { "$ref": "#/components/schemas/RequestStatus" }, "transactionHash": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" } } }, "RequestListResponse": { "type": "object", "properties": { "requests": { "type": "array", "items": { "$ref": "#/components/schemas/RequestSummary" } }, "pagination": { "$ref": "#/components/schemas/Pagination" } } }, "RequestSummary": { "type": "object", "properties": { "requestId": { "type": "string", "format": "uuid" }, "requestNumber": { "type": "string" }, "requestType": { "type": "string" }, "status": { "$ref": "#/components/schemas/RequestStatus" }, "applicantName": { "type": "string" }, "currentStage": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } }, "RequestDetailResponse": { "type": "object", "properties": { "requestId": { "type": "string", "format": "uuid" }, "requestNumber": { "type": "string" }, "tokenId": { "type": "integer" }, "requestType": { "type": "string" }, "status": { "$ref": "#/components/schemas/RequestStatus" }, "applicant": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "email": { "type": "string" } } }, "metadata": { "type": "object" }, "documents": { "type": "array", "items": { "$ref": "#/components/schemas/Document" } }, "approvals": { "type": "array", "items": { "$ref": "#/components/schemas/Approval" } }, "currentStage": { "$ref": "#/components/schemas/WorkflowStage" }, "timeline": { "type": "array", "items": { "$ref": "#/components/schemas/TimelineEvent" } }, "blockchainData": { "type": "object", "properties": { "tokenId": { "type": "integer" }, "contractAddress": { "type": "string" }, "creationTxHash": { "type": "string" } } }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "submittedAt": { "type": "string", "format": "date-time" }, "approvedAt": { "type": "string", "format": "date-time" } } }, "DocumentResponse": { "type": "object", "properties": { "documentId": { "type": "string", "format": "uuid" }, "docType": { "type": "string" }, "hash": { "type": "string" }, "version": { "type": "integer" }, "transactionHash": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" } } }, "DocumentDetailResponse": { "type": "object", "properties": { "documentId": { "type": "string", "format": "uuid" }, "docType": { "type": "string" }, "originalFilename": { "type": "string" }, "currentVersion": { "type": "integer" }, "currentHash": { "type": "string" }, "versions": { "type": "array", "items": { "$ref": "#/components/schemas/DocumentVersion" } }, "downloadUrl": { "type": "string", "format": "uri" } } }, "ApprovalResponse": { "type": "object", "properties": { "approvalId": { "type": "string", "format": "uuid" }, "status": { "$ref": "#/components/schemas/ApprovalStatus" }, "transactionHash": { "type": "string" }, "workflowStatus": { "type": "object", "properties": { "currentStage": { "type": "string" }, "isComplete": { "type": "boolean" }, "nextPendingDepartments": { "type": "array", "items": { "type": "string" } } } } } }, "DepartmentResponse": { "type": "object", "properties": { "code": { "type": "string" }, "name": { "type": "string" }, "walletAddress": { "type": "string" }, "apiKey": { "type": "string", "description": "Shown only on creation" }, "apiSecret": { "type": "string", "description": "Shown only on creation" }, "isActive": { "type": "boolean" }, "createdAt": { "type": "string", "format": "date-time" } } }, "VerificationResponse": { "type": "object", "properties": { "isValid": { "type": "boolean" }, "tokenId": { "type": "integer" }, "requestNumber": { "type": "string" }, "requestType": { "type": "string" }, "status": { "$ref": "#/components/schemas/RequestStatus" }, "applicantName": { "type": "string" }, "issuedAt": { "type": "string", "format": "date-time" }, "expiresAt": { "type": "string", "format": "date-time" }, "approvals": { "type": "array", "items": { "type": "object", "properties": { "departmentName": { "type": "string" }, "approvedAt": { "type": "string", "format": "date-time" } } } }, "blockchainProof": { "type": "object", "properties": { "contractAddress": { "type": "string" }, "tokenId": { "type": "integer" }, "ownerAddress": { "type": "string" }, "transactionHash": { "type": "string" } } } } }, "Document": { "type": "object", "properties": { "documentId": { "type": "string", "format": "uuid" }, "docType": { "type": "string" }, "originalFilename": { "type": "string" }, "currentVersion": { "type": "integer" }, "currentHash": { "type": "string" }, "uploadedAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } }, "DocumentVersion": { "type": "object", "properties": { "version": { "type": "integer" }, "hash": { "type": "string" }, "fileSize": { "type": "integer" }, "mimeType": { "type": "string" }, "uploadedBy": { "type": "string" }, "transactionHash": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" } } }, "Approval": { "type": "object", "properties": { "approvalId": { "type": "string", "format": "uuid" }, "departmentCode": { "type": "string" }, "departmentName": { "type": "string" }, "status": { "$ref": "#/components/schemas/ApprovalStatus" }, "remarks": { "type": "string" }, "reviewedDocuments": { "type": "array", "items": { "type": "string" } }, "isActive": { "type": "boolean" }, "transactionHash": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "invalidatedAt": { "type": "string", "format": "date-time" }, "invalidationReason": { "type": "string" } } }, "Department": { "type": "object", "properties": { "code": { "type": "string" }, "name": { "type": "string" }, "walletAddress": { "type": "string" }, "webhookUrl": { "type": "string" }, "isActive": { "type": "boolean" }, "createdAt": { "type": "string", "format": "date-time" } } }, "Workflow": { "type": "object", "properties": { "workflowId": { "type": "string", "format": "uuid" }, "workflowType": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "version": { "type": "integer" }, "isActive": { "type": "boolean" }, "stages": { "type": "array", "items": { "$ref": "#/components/schemas/WorkflowStage" } }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } }, "WorkflowStage": { "type": "object", "properties": { "stageId": { "type": "string" }, "stageName": { "type": "string" }, "stageOrder": { "type": "integer" }, "executionType": { "type": "string", "enum": [ "SEQUENTIAL", "PARALLEL" ] }, "requiredApprovals": { "type": "array", "items": { "type": "object", "properties": { "departmentCode": { "type": "string" }, "departmentName": { "type": "string" }, "requiredDocuments": { "type": "array", "items": { "type": "string" } }, "isMandatory": { "type": "boolean" } } } }, "completionCriteria": { "type": "string", "enum": [ "ALL", "ANY", "THRESHOLD" ] }, "threshold": { "type": "integer" }, "timeoutDays": { "type": "integer" }, "onTimeout": { "type": "string" }, "onRejection": { "type": "string" } } }, "Webhook": { "type": "object", "properties": { "webhookId": { "type": "string", "format": "uuid" }, "departmentCode": { "type": "string" }, "url": { "type": "string", "format": "uri" }, "events": { "type": "array", "items": { "type": "string" } }, "isActive": { "type": "boolean" }, "createdAt": { "type": "string", "format": "date-time" } } }, "WebhookLog": { "type": "object", "properties": { "logId": { "type": "string", "format": "uuid" }, "webhookId": { "type": "string", "format": "uuid" }, "eventType": { "type": "string" }, "payload": { "type": "object" }, "responseStatus": { "type": "integer" }, "responseTime": { "type": "integer" }, "retryCount": { "type": "integer" }, "createdAt": { "type": "string", "format": "date-time" } } }, "TimelineEvent": { "type": "object", "properties": { "eventId": { "type": "string", "format": "uuid" }, "eventType": { "type": "string", "enum": [ "REQUEST_CREATED", "REQUEST_SUBMITTED", "DOCUMENT_UPLOADED", "DOCUMENT_UPDATED", "APPROVAL_RECEIVED", "REJECTION_RECEIVED", "CHANGES_REQUESTED", "REQUEST_APPROVED", "REQUEST_REJECTED", "NFT_MINTED" ] }, "description": { "type": "string" }, "actor": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "APPLICANT", "DEPARTMENT", "SYSTEM" ] }, "id": { "type": "string" }, "name": { "type": "string" } } }, "metadata": { "type": "object" }, "transactionHash": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" } } }, "AuditLog": { "type": "object", "properties": { "logId": { "type": "string", "format": "uuid" }, "entityType": { "type": "string" }, "entityId": { "type": "string", "format": "uuid" }, "action": { "type": "string" }, "actorType": { "type": "string" }, "actorId": { "type": "string", "format": "uuid" }, "oldValue": { "type": "object" }, "newValue": { "type": "object" }, "ipAddress": { "type": "string" }, "userAgent": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" } } }, "BlockchainTransaction": { "type": "object", "properties": { "txId": { "type": "string", "format": "uuid" }, "txHash": { "type": "string" }, "txType": { "type": "string", "enum": [ "MINT_NFT", "APPROVAL", "DOC_UPDATE", "REJECT", "REVOKE" ] }, "relatedEntityType": { "type": "string" }, "relatedEntityId": { "type": "string", "format": "uuid" }, "fromAddress": { "type": "string" }, "toAddress": { "type": "string" }, "status": { "type": "string", "enum": [ "PENDING", "CONFIRMED", "FAILED" ] }, "blockNumber": { "type": "integer" }, "gasUsed": { "type": "integer" }, "errorMessage": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "confirmedAt": { "type": "string", "format": "date-time" } } }, "RequestStatus": { "type": "string", "enum": [ "DRAFT", "SUBMITTED", "IN_REVIEW", "PENDING_RESUBMISSION", "APPROVED", "REJECTED", "REVOKED", "CANCELLED" ] }, "ApprovalStatus": { "type": "string", "enum": [ "PENDING", "APPROVED", "REJECTED", "CHANGES_REQUESTED", "REVIEW_REQUIRED" ] }, "Pagination": { "type": "object", "properties": { "page": { "type": "integer" }, "limit": { "type": "integer" }, "total": { "type": "integer" }, "totalPages": { "type": "integer" }, "hasNext": { "type": "boolean" }, "hasPrev": { "type": "boolean" } } }, "Error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "details": { "type": "object" }, "timestamp": { "type": "string", "format": "date-time" }, "path": { "type": "string" } } } } } }