TELS Files Service - API Documentation

🏠 Home tels-files / tels-files / docs

TELS Files Service - API Documentation

Overview

Authentication

JWT Bearer

Standard JWT Bearer token authentication:

Authorization: Bearer <access_token>

Token validation: - Signing: Symmetric key from AUTH__SIGNING_KEY environment variable - Lifetime: Validated - Issuer/Audience: Not validated

Custom Authorization

Persona-based access control applied to all endpoints: - Personas: DirectSupplyPartner, Customer - Facility Authorization: Per-request facility-level access validation via FacilityAuthorizationService


Files Controller

Route Prefix: /files API Version: v1 Authorization: JWT Bearer + Custom (DirectSupplyPartner | Customer)

Method Path Description
POST /files Upload file with metadata
GET /files/{fileId} Download file
GET /files/{fileId}/metadata Get file metadata
PUT /files/{fileId}/metadata Update file metadata (full)
PATCH /files/{fileId}/metadata Update file metadata (partial)
DELETE /files/{fileId} Delete file (soft delete)
GET /files/facilities/{facilityId}/metadata Search file metadata

POST /files

Upload a file with metadata.

Content-Type: multipart/form-data

Request: - file (IFormFile, required) — The file content - metadata (FileUploadMetadata, required) — File metadata

FileUploadMetadata:

{
  "fileId": "guid (optional, auto-generated if omitted)",
  "facilityId": 12345,
  "fileGroupId": 1,
  "fileDate": "2026-03-11",
  "enabledForDocumentation": true,
  "externalReferences": [
    {
      "domain": "Tasks",
      "type": "WorkOrder",
      "identifier": "67890"
    }
  ]
}

Response (200 OK):

"3fa85f64-5717-4562-b3fc-2c963f66afa6"

Processing: 1. Validates metadata and file content 2. Uploads file content to Unity File Handler (Base64-encoded) 3. Saves file metadata to SQL Server (Files.Files) 4. Creates composite identifier references if provided


GET /files/{fileId}

Download a file by its GUID.

Path Parameters: - fileId (GUID, required) — File identifier

Response (200 OK): FileStreamResult — File content stream with appropriate content type

Processing: 1. Looks up file metadata from SQL Server 2. Retrieves file content stream from Unity File Handler 3. Returns file with original content type and file name


GET /files/{fileId}/metadata

Get metadata for a specific file.

Path Parameters: - fileId (GUID, required) — File identifier

Response (200 OK):

{
  "fileId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "facilityId": 12345,
  "fileName": "report.pdf",
  "contentType": "application/pdf",
  "fileSize": 1048576,
  "fileDate": "2026-03-11",
  "uploadedWhenUTC": "2026-03-11T10:00:00Z",
  "uploadedWhoName": "John Smith",
  "enabledForDocumentation": true,
  "fileGroupId": 1,
  "searchTerm": "quarterly report",
  "externalReferences": [
    {
      "domain": "Tasks",
      "type": "WorkOrder",
      "identifier": "67890"
    }
  ]
}

PUT /files/{fileId}/metadata

Full update of file metadata.

Path Parameters: - fileId (GUID, required) — File identifier

Request Body:

{
  "fileName": "updated-report.pdf",
  "fileGroupId": 2,
  "fileDate": "2026-03-15",
  "enabledForDocumentation": false,
  "searchTerm": "updated quarterly report",
  "externalReferences": [
    {
      "domain": "Tasks",
      "type": "WorkOrder",
      "identifier": "67890"
    }
  ]
}

Response: 204 No Content


PATCH /files/{fileId}/metadata

Partial update of file metadata (only specified fields are updated).

Path Parameters: - fileId (GUID, required) — File identifier

Request Body (PatchFileMetadataRequest — all fields nullable):

{
  "facilityId": 12346,
  "fileName": "renamed-report.pdf",
  "fileGroupId": 3,
  "fileDate": "2026-04-01",
  "enabledForDocumentation": true,
  "searchTerm": "new search term",
  "externalReferences": [
    {
      "domain": "Assets",
      "type": "Asset",
      "identifier": "A-100"
    }
  ]
}

Response: 204 No Content


DELETE /files/{fileId}

Soft delete a file (sets IsActive = false).

Path Parameters: - fileId (GUID, required) — File identifier

Response: 200 OK


GET /files/facilities/{facilityId}/metadata

Search file metadata for a facility with filtering and pagination.

Path Parameters: - facilityId (int, required) — Facility identifier

Query Parameters: - fileGroups (string, optional) — Comma-separated file group IDs to filter by - minFileDate (date, optional) — Minimum file date filter - maxFileDate (date, optional) — Maximum file date filter - excludeFilesWithFileGroups (bool, optional) — Exclude files that belong to a file group - excludeFilesWithExternalReferences (bool, optional) — Exclude files that have external references - searchTerm (string, optional) — Text search filter - nextPageKey (string, optional) — Pagination cursor from previous response

Response (200 OK):

{
  "fileMetadata": [
    {
      "fileId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "facilityId": 12345,
      "fileName": "report.pdf",
      "contentType": "application/pdf",
      "fileSize": 1048576,
      "fileDate": "2026-03-11",
      "uploadedWhenUTC": "2026-03-11T10:00:00Z",
      "uploadedWhoName": "John Smith",
      "enabledForDocumentation": true,
      "fileGroupId": 1,
      "searchTerm": "quarterly report",
      "externalReferences": []
    }
  ],
  "nextPageKey": "eyJwYWdlIjoyfQ==",
  "total": 42
}

File Groups Controller

Route Prefix: /files/fileGroups API Version: v1 Authorization: JWT Bearer + Custom (DirectSupplyPartner | Customer)

Method Path Description
GET /files/fileGroups Get file groups
GET /files/fileGroups/{fileGroupId} Get single file group
POST /files/fileGroups Create file group
PUT /files/fileGroups/{fileGroupId} Update file group
PATCH /files/fileGroups/{fileGroupId} Patch file group
DELETE /files/fileGroups/{fileGroupId} Delete file group

GET /files/fileGroups

Get file groups with optional filtering.

Query Parameters: - chainId (int, optional) — Filter by chain/organization - externalReferences (string, optional) — Filter by external references

Response (200 OK):

[
  {
    "fileGroupId": 1,
    "fileGroupName": "Inspection Reports",
    "chainId": 100,
    "externalReferences": [
      {
        "domain": "Assets",
        "type": "AssetType",
        "identifier": "HVAC"
      }
    ]
  }
]

GET /files/fileGroups/{fileGroupId}

Get a single file group by ID.

Path Parameters: - fileGroupId (int, required)

Response (200 OK):

{
  "fileGroupId": 1,
  "fileGroupName": "Inspection Reports",
  "chainId": 100,
  "externalReferences": []
}

POST /files/fileGroups

Create a new file group.

Request Body:

{
  "chainId": 100,
  "fileGroupName": "Maintenance Photos",
  "externalReferences": [
    {
      "domain": "Assets",
      "type": "AssetType",
      "identifier": "Plumbing"
    }
  ]
}

Response (200 OK):

1

PUT /files/fileGroups/{fileGroupId}

Full update of a file group.

Path Parameters: - fileGroupId (int, required)

Request Body:

{
  "fileGroupName": "Updated Group Name",
  "chainId": 200,
  "externalReferences": []
}

Response: 204 No Content


PATCH /files/fileGroups/{fileGroupId}

Partial update of a file group.

Path Parameters: - fileGroupId (int, required)

Request Body (all fields nullable):

{
  "fileGroupName": "Renamed Group"
}

Response: 204 No Content


DELETE /files/fileGroups/{fileGroupId}

Delete a file group.

Path Parameters: - fileGroupId (int, required)

Response: 204 No Content


Key Data Contracts

FileMetadata

{
  "fileId": "guid",
  "facilityId": 12345,
  "fileName": "report.pdf",
  "contentType": "application/pdf",
  "fileSize": 1048576,
  "fileDate": "2026-03-11",
  "uploadedWhenUTC": "2026-03-11T10:00:00Z",
  "uploadedWhoName": "John Smith",
  "enabledForDocumentation": true,
  "fileGroupId": 1,
  "searchTerm": "quarterly report",
  "externalReferences": [
    {
      "domain": "Tasks",
      "type": "WorkOrder",
      "identifier": "67890"
    }
  ]
}

CompositeIdentifier

{
  "domain": "Tasks",
  "type": "WorkOrder",
  "identifier": "67890"
}

FileGroup

{
  "fileGroupId": 1,
  "fileGroupName": "Inspection Reports",
  "chainId": 100,
  "externalReferences": []
}

FileMetadataResponse (Paginated)

{
  "fileMetadata": [],
  "nextPageKey": "cursor-string",
  "total": 42
}

Global Response Codes

Code Meaning
200 Success
204 No Content (successful update/delete)
400 Bad Request — validation error
401 Unauthorized — invalid or missing JWT token
403 Forbidden — insufficient persona or facility access
404 Not Found — file or file group does not exist

Notes