Download or view files inline from Tallyfy using GET requests with your organization and file IDs. The response returns raw binary content with appropriate headers.
Get file metadata
GET /organizations/{org_id}/assets/{asset_id}
This endpoint retrieves metadata for a specific uploaded file (called an “asset” in Tallyfy’s API). It returns details like the filename, upload date, and which object the file is attached to.
Replace {org_id} with your Organization ID and {asset_id} with the asset ID of the file you want metadata for.
Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClient
const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const assetId = 'ASSET_ID_TO_GET_METADATA';const apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/assets/${assetId}`;
const headers = new Headers();headers.append('Authorization', `Bearer ${accessToken}`);headers.append('Accept', 'application/json');headers.append('X-Tallyfy-Client', 'APIClient');
fetch(apiUrl, { method: 'GET', headers: headers}).then(response => { if (!response.ok) { return response.json() .catch(() => response.text()) .then(errData => { console.error(`Error response for asset ${assetId}:`, errData); throw new Error(`HTTP error! status: ${response.status}`); }); } return response.json();}).then(data => { console.log(`Metadata for asset ${assetId}:`); console.log(JSON.stringify(data, null, 2));}).catch(error => { console.error(`Error getting asset metadata ${assetId}:`, error.message);});import requestsimport jsonimport os
access_token = os.environ.get('TALLYFY_ACCESS_TOKEN', 'YOUR_PERSONAL_ACCESS_TOKEN')org_id = os.environ.get('TALLYFY_ORG_ID', 'YOUR_ORGANIZATION_ID')asset_id = 'ASSET_ID_TO_GET_METADATA'api_url = f'https://go.tallyfy.com/api/organizations/{org_id}/assets/{asset_id}'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient'}
response = Nonetry: response = requests.get(api_url, headers=headers) response.raise_for_status()
metadata = response.json() print(f'Metadata for asset {asset_id}:') print(json.dumps(metadata, indent=4))
except requests.exceptions.HTTPError as http_err: print(f"HTTP error for asset {asset_id}: {http_err}") if response is not None: print(f"Response Body: {response.text}")except requests.exceptions.RequestException as req_err: print(f"Request failed for asset {asset_id}: {req_err}")except json.JSONDecodeError: print(f"Failed to decode JSON for asset {asset_id}") if response is not None: print(f"Response Text: {response.text}")import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.io.IOException;
public class GetFileMetadata { public static void main(String[] args) { String accessToken = System.getenv().getOrDefault("TALLYFY_ACCESS_TOKEN", "YOUR_PERSONAL_ACCESS_TOKEN"); String orgId = System.getenv().getOrDefault("TALLYFY_ORG_ID", "YOUR_ORGANIZATION_ID"); String assetId = "ASSET_ID_TO_GET_METADATA"; String apiUrl = String.format("https://go.tallyfy.com/api/organizations/%s/assets/%s", orgId, assetId);
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .header("Authorization", "Bearer " + accessToken) .header("Accept", "application/json") .header("X-Tallyfy-Client", "APIClient") .GET() .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) { System.out.println("Metadata for asset " + assetId + ":"); System.out.println(response.body()); } else { System.err.println("Failed to get metadata for asset " + assetId + ". Status: " + response.statusCode()); System.err.println("Response Body: " + response.body()); } } catch (IOException | InterruptedException e) { System.err.println("Request failed: " + e.getMessage()); Thread.currentThread().interrupt(); } }}package main
import ( "encoding/json" "fmt" "io/ioutil" "net/http" "os" "time")
func main() { accessToken := os.Getenv("TALLYFY_ACCESS_TOKEN") if accessToken == "" { accessToken = "YOUR_PERSONAL_ACCESS_TOKEN" } orgId := os.Getenv("TALLYFY_ORG_ID") if orgId == "" { orgId = "YOUR_ORGANIZATION_ID" } assetId := "ASSET_ID_TO_GET_METADATA" apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/assets/%s", orgId, assetId)
client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", apiUrl, nil) if err != nil { fmt.Printf("Error creating request: %v\n", err) return }
req.Header.Set("Authorization", "Bearer "+accessToken) req.Header.Set("Accept", "application/json") req.Header.Set("X-Tallyfy-Client", "APIClient")
resp, err := client.Do(req) if err != nil { fmt.Printf("Error making request: %v\n", err) return } defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading response: %v\n", err) return }
if resp.StatusCode != http.StatusOK { fmt.Printf("Failed. Status: %d\nBody: %s\n", resp.StatusCode, string(body)) return }
var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { fmt.Printf("Error parsing JSON: %v\nRaw: %s\n", err, string(body)) return }
prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Println(string(prettyJSON))}#include <iostream>#include <string>#include <cpprest/http_client.h>#include <cpprest/filestream.h>
using namespace web;using namespace web::http;using namespace web::http::client;
pplx::task<void> GetAssetMetadata(const utility::string_t& assetId){ utility::string_t accessToken = U("YOUR_PERSONAL_ACCESS_TOKEN"); utility::string_t orgId = U("YOUR_ORGANIZATION_ID"); utility::string_t apiUrl = U("https://go.tallyfy.com/api/organizations/") + orgId + U("/assets/") + assetId;
http_client client(apiUrl);
http_request request(methods::GET); request.headers().add(U("Authorization"), U("Bearer ") + accessToken); request.headers().add(U("Accept"), U("application/json")); request.headers().add(U("X-Tallyfy-Client"), U("APIClient"));
return client.request(request).then([assetId](http_response response) { utility::string_t assetIdW = assetId; if (response.status_code() == status_codes::OK) { return response.extract_json().then([assetIdW](json::value v) { std::wcout << L"Metadata for asset " << assetIdW << L":\n" << v.serialize() << std::endl; }); } else { return response.extract_string().then([response, assetIdW](utility::string_t body) { std::wcerr << L"Failed. Status: " << response.status_code() << std::endl; std::wcerr << L"Body: " << body << std::endl; return pplx::task_from_exception<void>(std::runtime_error("API request failed")); }); } });}
int main(){ utility::string_t assetToGet = U("ASSET_ID_TO_GET_METADATA"); try { GetAssetMetadata(assetToGet).wait(); } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } return 0;}// Requires C++ REST SDK (Casablanca).using System;using System.Net.Http;using System.Net.Http.Headers;using System.Text.Json;using System.Threading.Tasks;
public class TallyfyAssetMetadata{ private static readonly HttpClient client = new HttpClient();
public static async Task GetMetadataAsync(string assetId) { var accessToken = Environment.GetEnvironmentVariable("TALLYFY_ACCESS_TOKEN") ?? "YOUR_PERSONAL_ACCESS_TOKEN"; var orgId = Environment.GetEnvironmentVariable("TALLYFY_ORG_ID") ?? "YOUR_ORGANIZATION_ID"; var apiUrl = $"https://go.tallyfy.com/api/organizations/{orgId}/assets/{assetId}";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("X-Tallyfy-Client", "APIClient");
try { HttpResponseMessage response = await client.GetAsync(apiUrl); string responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) { Console.WriteLine($"Metadata for asset {assetId}:"); var doc = JsonDocument.Parse(responseBody); Console.WriteLine(JsonSerializer.Serialize(doc, new JsonSerializerOptions { WriteIndented = true })); } else { Console.WriteLine($"Failed. Status: {response.StatusCode}"); Console.WriteLine($"Body: {responseBody}"); } } catch (HttpRequestException e) { Console.WriteLine($"Request error: {e.Message}"); } }
// static async Task Main(string[] args) // { // await GetMetadataAsync("ASSET_ID_TO_GET_METADATA"); // }}A successful request returns a 200 OK status and a JSON object with the asset metadata inside a data property.
{ "data": { "id": "ASSET_ID_TO_GET_METADATA", "filename": "report_q1.pdf", "version": 1, "uploaded_from": "capture_id_abc123", "uploaded_at": "2024-03-15T10:30:00Z", "step_id": "step_id_xyz789", "source": "local", "system": null, "uploaded_to_s3": true, "subject": { "id": "run_id_or_checklist_id", "type": "Run" } }}Key fields in the response:
| Field | Description |
|---|---|
id | Unique asset identifier |
filename | Original filename of the uploaded file |
version | Version number of the asset |
uploaded_from | Form field ID the file was uploaded from, or ko_field for kick-off fields |
uploaded_at | Timestamp when the file was uploaded |
step_id | Step ID if the file is attached to a task step (can be null) |
source | Upload source - defaults to local |
system | External storage system if applicable (e.g., Dropbox, Google Drive) |
uploaded_to_s3 | Whether the file was stored in S3 |
subject | Object containing the parent’s id and type (e.g., Run, Checklist, Organization) |
If the asset ID isn’t found or you don’t have permission, you’ll get a 404 or 403 error.
Tallyfy’s API lets you upload, download, get metadata for, and delete files attached to tasks or kick-off forms using multipart form data and S3 storage.
A DELETE endpoint that permanently removes an uploaded file from a task or kick-off form field using /organizations/[org_id]/file/[asset_id] and returns a 200 OK status with an empty response body.
Attaching files to form fields via Tallyfy’s API requires uploading the file to get an asset reference and then updating the task or process to link that asset to the specific form field.
Was this helpful?
About Tallyfy
- 2025 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks