Tallyfy’s API lets you upload files up to 100MB and attach them to tasks or kick-off forms. You…
Get file metadata
Endpoint
Section titled “Endpoint”GET /organizations/{org_id}/assets/{asset_id}
This gets the details of one uploaded file. Tallyfy’s API calls a file an “asset”. You get details like the filename, the upload date, and what the file is attached to.
Request
Section titled “Request”Replace {org_id} with your organization ID. Replace {asset_id} with the file’s asset ID.
Headers
Section titled “Headers”Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClient
Code samples
Section titled “Code samples”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"); // }}Response
Section titled “Response”You’ll get 200 OK. The file’s details are in the data property of the JSON.
{ "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) |
You’ll get an error if the asset ID isn’t found or you don’t have permission. The status code is 404 or 403.
Related articles
Section titled “Related articles” Tallyfy’s API provides two GET endpoints for retrieving uploaded files: one that returns the…
Tallyfy”s API uses a two-step process to attach files to form fields. First upload the file via…
Tallyfy’s API lets you permanently delete an uploaded file and its storage record by sending a…
Was this helpful?
About Tallyfy
- 2026 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks