Guide for Retrieving Files

Overview

Files in Origami are stored independently and linked to parent records (Claims, Incidents, Policies, Locations, etc.) through a polymorphic Links table. This guide walks through the practical steps for discovering, identifying, and downloading files via the API.

Key Endpoints for File Retrieval

EndpointPurpose
GET /api/{domain}/{id}/FilesList files attached to a specific parent (ie,{domain}) record
GET /api/File/QueryList files across the system (metadata only, no parent info)
GET /api/File/{id}Get a single file's metadata and/or binary content

Key Endpoints for Relationship Discovery (identifying a file's parent)

EndpointPurpose
GET /api/Link/QueryFind which parent record a file is attached to (returns numeric DomainIDs)
GET /api/Domains *Resolve numeric DomainIDs from Link/Query to human-readable domain names

*Note: GET /api/Domains is not needed for file retrieval itself. It is only relevant when you need to interpret the ParentDomainID or ChildDomainID values returned by /api/Link/Query.

Scenario 1: Get Files for a Known Parent Record

  1. If you already know the parent (e.g., Claim 13712), start by listing the metadata for each attach file:
GET /api/Claim/13712/Files?columns=FileID,FileName,Description,MimeType,EntryDate,FileSize

Response:

{
  "List": [
    {
      "FileID": 10204,
      "FileName": "PropertyDiagram.png",
      "Description": "Site diagram",
      "MimeType": ".png",
      "EntryDate": "2025-04-15T14:42:20.707",
      "FileSize": 37133
    }
  ]
}
  1. Then get the actual file content for any individual file:
GET /api/File/10204?columns=FileID,FileName,MimeType,Contents

This returns the file bytes as a base64-encoded Contents value (see Scenario 4 for full details).

Can you include Contents directly in the parent Files call? Technically yes:

GET /api/Claim/13712/Files?columns=FileID,FileName,Contents&take=1

This works but is risky for multi-file results because it loads all file bytes into memory simultaneously. The recommended pattern is: list files first (to get FileIDs), then retrieve content one file at a time via GET /api/File/{id}.

Scenario 2: List Files Without Knowing the Parent Record ID

GET /api/File/Query?columns=FileID,FileName,Description,MimeType,EntryDate,FileSize,IsUnlinked&sort=EntryDate desc

This returns file metadata but does NOT include information about which parent record each file is attached to. The IsUnlinked column indicates whether the file has any parent association (false = linked, true = orphaned/unlinked).

Scenario 3: Find a File's Parent Record

Starting from a FileID (e.g., 10204), query the Links table to find the parent:

GET /api/Link/Query?childDomain=File&childRecordID=10204&columns=ParentDomainID,ParentID,ChildID

Response:

{
  "List": [
    {
      "ParentDomainID": 1,
      "ParentID": 13712,
      "ChildID": 10204
    }
  ]
}

Resolving the ParentDomainID

The Link response returns numeric DomainIDs, not domain names. The core DomainIDs are fixed across all environments:

DomainIDDomain Name
1Claim
2Contact
3Location
4File
5Note
6Policy
7Task
11Incident

For a complete list (including custom entities with higher IDs), call:

GET /api/Domains

This returns all domains the authenticated user has access to, with DomainID, Name, DisplayNameSingular, and DisplayNamePlural.

Once you've resolved ParentDomainID = 1 to Claim, you can fetch the parent record:

GET /api/Claim/13712

ℹ️ Pro Tip: Use Filter Parameters to Skip DomainID Resolution

When querying Links, you can treat parentDomain as a filter to return only files linked to that object type:

GET /api/Link/Query?childDomain=File&parentDomain=Claim&columns=ParentID,ChildID

In this case, every row in the response is a Claim-to-File link, so the DomainID columns become unnecessary.

Scenario 4: Download a File

There are two approaches for retrieving the actual file content.

Option A: Contents Column (Recommended for API Integrations)

Request the Contents column on GET /api/File/{id}:

GET /api/File/10204?columns=FileID,FileName,MimeType,Contents

Response:

{
  "Record": {
    "FileID": 10204,
    "FileName": "PropertyDiagram.png",
    "MimeType": ".png",
    "Contents": "iVBORw0KGgoAAAANSUhEUgAA...(base64)..."
  },
  "Domain": "File",
  "Id": 10204
}

The Contents value is a base64-encoded byte array of the file. This works reliably with token-based API authentication. The response uses the single-record GET /api/{domain}/{id} format (with Record instead of List).

Restriction: The Contents column is only practical on single-record queries (GET /api/File/{id}). While not explicitly blocked by attribute, requesting it on multi-record queries would attempt to load all file bytes into memory simultaneously.

Option B: DownloadURL Column

Include DownloadURL in your columns list:

GET /api/Claim/13712/Files?columns=FileID,FileName,DownloadURL

The returned URL is a web application URL (not an API endpoint). It is relative to the base application URL and requires web session authentication to use.

Known limitations of DownloadURL:

  • Returns empty string for external files (those with ExternalFileRepositoryID or ExternalDirectURL)
  • Returns empty string if the user has the RestrictDownload permission without Full permission
  • Bug: Throws a server error ("Object reference not set to an instance of an object") when the Origami.EnableEnhancedSessionIDSecurity setting is disabled.

For API-only workflows, Option A (Contents column) is the recommended approach.

Complete Workflow: From Scratch to Downloaded File

Step 1: Find files on a Claim
  GET /api/Claim/13712/Files?columns=FileID,FileName,MimeType,FileSize

Step 2: Download a specific file
  GET /api/File/10204?columns=FileID,FileName,Contents

Step 3: Decode the base64 Contents value to get the raw file bytes

Complete Workflow: Starting from a FileID

Step 1: Get file metadata
  GET /api/File/10204?columns=FileID,FileName,MimeType,Description

Step 2: Find what it's attached to
  GET /api/Link/Query?childDomain=File&childRecordID=10204&columns=ParentDomainID,ParentID

Step 3: Resolve ParentDomainID (if needed)
  GET /api/Domains
  (or use the static DomainID table above for core domains)

Step 4: Fetch the parent record
  GET /api/Claim/13712

Step 5: Download the file
  GET /api/File/10204?columns=FileID,FileName,Contents

Available File Columns

When querying files (via /api/File/Query, /api/File/{id}, or /api/{domain}/{id}/Files), these are commonly useful columns:

ColumnDescription
FileIDUnique identifier
FileNameOriginal file name with extension
DescriptionUser-provided description
MimeTypeFile type (e.g., .pdf, .png, .docx)
FileSizeSize in bytes
EntryDateUpload timestamp
EntryUserIDUser who uploaded the file
ModifiedDateLast modification timestamp
ModifiedUserIDUser who last modified
DownloadedDateLast download timestamp
DownloadedUserIDUser who last downloaded
DocumentStatusIDDocument workflow status
SourceTypeOrigin indicator (e.g., "U" for user upload)
IsUnlinkedWhether the file is attached to a parent record
UnlinkedAccessModeAccess mode for unlinked files
ContentsBase64-encoded file bytes (single-record queries only)
DownloadURLWeb application download link (see limitations above)