eTMF

The eTMF (Electronic Trial Master File) API enables you to manage clinical trial documentation programmatically. Use this API to query study details, retrieve filing levels, list artifacts and milestones, and import documents into your studies.

Note: All eTMF API endpoints require the Egnyte.etmf OAuth scope.

Base URL

https://{domain}.egnyte.com/pubapi/v1/etmf

Authentication

All requests require an OAuth 2.0 Bearer token in the Authorization header:

Authorization: Bearer {access_token}

See Authentication for details on obtaining a token with the Egnyte.etmf scope.


List Studies

Retrieve all studies the authenticated user has access to.

Request

GET /pubapi/v1/etmf/studies

Path Parameters

This endpoint does not require path parameters.

Query Parameters

This endpoint does not require query parameters.

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/etmf/studies" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

200 OK

FieldTypeDescription
studiesarrayList of study objects
studies[].systemIdstringUnique system identifier for the study
studies[].idstringHuman-readable study identifier
studies[].namestringDisplay name of the study
studies[].descriptionstringStudy description
studies[].statusstringStudy status (e.g., ACTIVE)

Example Response

{
  "studies": [
    {
      "systemId": "eee92526-53ce-45be-bdce-7263567c9e78",
      "id": "DEM-81",
      "name": "Demo 81 Study",
      "description": "Acme Tx is conducting a study to evaluate the impact of DEM-81 on...",
      "status": "ACTIVE"
    }
  ]
}

List Filing Levels

Retrieve the filing level hierarchy (trial, countries, and sites) for a specific study.

Request

GET /pubapi/v1/etmf/studies/{studyId}/filing-levels

Path Parameters

ParameterTypeRequiredDescription
studyIdstringYesSystem ID of the study

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/etmf/studies/{studyId}/filing-levels" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

200 OK

FieldTypeDescription
trialobjectTrial-level filing information
trial.systemIdstringSystem ID of the trial filing level
trial.statusstringTrial status (e.g., ACTIVE)
trial.countriesarrayList of countries in the trial
trial.countries[].systemIdstringSystem ID of the country filing level
trial.countries[].codestringISO country code
trial.countries[].statusstringCountry status
trial.countries[].sitesarrayList of sites within the country
trial.countries[].sites[].systemIdstringSystem ID of the site filing level
trial.countries[].sites[].idstringSite identifier
trial.countries[].sites[].statusstringSite status

Example Response

{
  "trial": {
    "systemId": "2f47005e-76d1-42e7-857c-926ca5723e18",
    "status": "ACTIVE",
    "countries": [
      {
        "systemId": "5ccfd52a-75f9-49c5-b2e0-177862699ed0",
        "code": "POL",
        "status": "ACTIVE",
        "sites": [
          {
            "systemId": "ab650679-ac09-4e1e-afd9-13de225ec4af",
            "id": "WAW_01",
            "status": "ACTIVE"
          }
        ]
      }
    ]
  }
}

List Artifacts and Milestones

Retrieve available artifacts and milestones for a specific filing level within a study.

Request

GET /pubapi/v1/etmf/studies/{studyId}/artifacts

Path Parameters

ParameterTypeRequiredDescription
studyIdstringYesSystem ID of the study

Query Parameters

ParameterTypeRequiredDescription
filingLevelstringYesType of filing level. One of: trial, country, site
filingLevelIdstringYesSystem ID of the filing level

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/etmf/studies/{studyId}/artifacts?filingLevel=trial&filingLevelId={filingLevelId}" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

200 OK

FieldTypeDescription
artifactsarrayList of artifact objects
artifacts[].referenceModelArtifactIdstringReference model artifact identifier
artifacts[].numberstringArtifact number (e.g., 01.01.01)
artifacts[].namestringArtifact name
artifacts[].isUnblindedbooleanWhether the artifact is unblinded
artifacts[].milestoneNumberintegerAssociated milestone number
milestonesarrayList of milestone objects
milestones[].idstringMilestone system ID
milestones[].namestringMilestone name
milestones[].numberintegerMilestone number
milestones[].statusstringMilestone status

Example Response

{
  "artifacts": [
    {
      "referenceModelArtifactId": "001",
      "number": "01.01.01",
      "name": "Trial Master File Plan",
      "isUnblinded": false,
      "milestoneNumber": 2
    }
  ],
  "milestones": [
    {
      "id": "aa9b50b7-f8ad-4cdd-a401-a6d23ee06568",
      "name": "Clinical Infrastructure Ready",
      "number": 2,
      "status": "ACTIVE"
    }
  ]
}

List Documents

Retrieve documents for a specific filing level with optional filtering by zone, artifact, and status. Supports pagination.

Request

POST /pubapi/v1/etmf/studies/{studyId}/documents/listing

Path Parameters

ParameterTypeRequiredDescription
studyIdstringYesSystem ID of the study

Request Body

FieldTypeRequiredDescription
filingLevel.typestringYesFiling level type. One of: TRIAL, COUNTRY, SITE
filingLevel.systemIdstringYesSystem ID of the filing level
zonestringNoFilter by zone (format: {number} {name}, e.g., 02 Central Trial Documents)
artifactstringNoFilter by artifact (format: {number} {name}, e.g., 02.01.01 Investigator's Brochure)
statusstringNoFilter by document status. One of: DRAFT, IN_QC, APPROVED, REJECTED
limitintegerNoMaximum number of documents to return (1-200). Default: 20
offsetintegerNoZero-based index for pagination. Default: 0

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/etmf/studies/{studyId}/documents/listing" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{ "filingLevel": { "type": "SITE", "systemId": "b53884cf-2bc0-4830-abba-a54c67c25a65" }, "zone": "02 Central Trial Documents", "artifact": "02.01.01 Investigator'

Response

200 OK

FieldTypeDescription
documentsarrayList of document objects
documents[].studyIdstringStudy system ID
documents[].idstringDocument system ID
documents[].artifactobjectArtifact classification details
documents[].artifact.artifactNumberstringArtifact number
documents[].artifact.artifactNamestringArtifact name
documents[].artifact.sectionNumberstringSection number
documents[].artifact.sectionNamestringSection name
documents[].artifact.zoneNumberstringZone number
documents[].artifact.zonestringZone name
documents[].artifact.referenceModelArtifactIdstringReference model artifact ID
documents[].artifact.isUnblindedbooleanWhether the artifact is unblinded
documents[].milestoneobjectAssociated milestone
documents[].milestone.namestringMilestone name
documents[].milestone.numberintegerMilestone number
documents[].milestone.idstringMilestone system ID
documents[].filingLevelobjectFiling level information
documents[].filingLevel.typestringFiling level type
documents[].fileobjectFile metadata
documents[].file.namestringFile name
documents[].file.entryIdstringFile entry ID
documents[].file.groupIdstringFile group ID
documents[].qualityControlobjectQuality control information
documents[].qualityControl.dueOnstringQC due date (ISO 8601 format)
documents[].qualityControl.statusstringQC status
offsetintegerCurrent offset value
hasMorebooleanWhether more results are available

Example Response

{
  "documents": [
    {
      "studyId": "ab650679-ac09-4e1e-afd9-13de225ec4af",
      "id": "ab650679-ac09-4e1e-afd9-13de225ec4af",
      "artifact": {
        "artifactNumber": "02.01.01",
        "artifactName": "Investigator's Brochure",
        "sectionNumber": "02.01",
        "sectionName": "Product and Trial Documentation",
        "zoneNumber": "02",
        "zone": "Central Trial Documents",
        "referenceModelArtifactId": "31",
        "isUnblinded": false
      },
      "milestone": {
        "name": "Clinical Infrastructure Ready",
        "number": 2,
        "id": "45f8cb40-0d8e-4f82-89c3-3708e4b0210d"
      },
      "filingLevel": {
        "type": "TRIAL"
      },
      "file": {
        "name": "Investigator Brochure v1 - 2024-02-14.docx",
        "entryId": "17c79408-6faf-4ba4-8be1-0b77a7511e60",
        "groupId": "aa5f47a4-4a02-425b-88ec-dcbe7fa7c2c2"
      },
      "qualityControl": {
        "dueOn": "2025-04-12T14:08:14.812Z",
        "status": "DRAFT"
      }
    }
  ],
  "offset": 0,
  "hasMore": true
}

Add Documents

Import a document into a study. The file must already exist in the Egnyte file system before calling this endpoint.

Request

POST /pubapi/v1/etmf/studies/{studyId}/documents

Path Parameters

ParameterTypeRequiredDescription
studyIdstringYesSystem ID of the study

Request Body

FieldTypeRequiredDescription
filingLevel.typestringYesFiling level type. One of: TRIAL, COUNTRY, SITE
filingLevel.systemIdstringYesSystem ID of the filing level
classification.referenceModelArtifactIdstringNoReference model artifact ID for classification
classification.milestoneIdstringNoMilestone system ID to associate with the document
classification.unblindedbooleanConditionalRequired when the document is unclassified. Indicates whether the document is unblinded
sourceFile.groupIdstringYesGroup ID of the file in the Egnyte file system

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/etmf/studies/{studyId}/documents" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "filingLevel": {
    "systemId": "aa9b50b7-f8ad-4cdd-a401-a6d23ee06568",
    "type": "TRIAL"
  },
  "classification": {
    "referenceModelArtifactId": "001",
    "milestoneId": "c8cfa0dd-dda3-4089-962d-3d33bb6ae448"
  },
  "sourceFile": {
    "groupId": "35ed2e11-35e8-4712-b78f-98aceb780ef8"
  }
}'

Response

200 OK

FieldTypeDescription
idstringSystem ID of the newly created document
fileobjectFile metadata
file.groupIdstringFile group ID
file.entryIdstringFile entry ID
file.pathstringFull path to the file in the eTMF structure

Example Response

{
  "id": "aa9b50b7-f8ad-4cdd-a401-a6d23ee06568",
  "file": {
    "groupId": "35ed2e11-35e8-4712-b78f-98aceb780ef8",
    "entryId": "5c8598b6-1ab4-45e5-b534-4b60caeddabd",
    "path": "/Shared/__eTMF__/STD-001_STAGING/Trial Binder/Artifacts/01 First Country RA Approval/02 Central Trial Documents/02.01 Product and Trial Documentation/02.01.01 Investigator's Brochure/example.pdf"
  }
}

Error Codes

StatusErrorDescriptionResolution
400Bad RequestInvalid request body or parametersVerify all required fields are present and correctly formatted
401UnauthorizedInvalid or expired OAuth tokenRefresh your OAuth token
403ForbiddenMissing Egnyte.etmf scope or insufficient permissionsEnsure your OAuth token includes the Egnyte.etmf scope and the user has access to the study
404Not FoundStudy, filing level, or file does not existVerify the studyId, filingLevelId, or groupId is correct
429Rate LimitedToo many requestsImplement exponential backoff; check the Retry-After header

Code Examples

List Studies

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/etmf/studies" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Add Document

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/etmf/studies/eee92526-53ce-45be-bdce-7263567c9e78/documents" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "filingLevel": {
    "systemId": "aa9b50b7-f8ad-4cdd-a401-a6d23ee06568",
    "type": "TRIAL"
  },
  "classification": {
    "referenceModelArtifactId": "001",
    "milestoneId": "c8cfa0dd-dda3-4089-962d-3d33bb6ae448"
  },
  "sourceFile": {
    "groupId": "35ed2e11-35e8-4712-b78f-98aceb780ef8"
  }
}'
  • Authentication — How to obtain OAuth tokens with the Egnyte.etmf scope
  • File System API — Upload and manage files before importing them into eTMF
  • Best Practices — Rate limiting, pagination, and error handling strategies