Tallyfy’s API lets you update any task (process or one-off) via a PUT request where you can change the title, deadline, assignees, form field values, and other properties — with assignee updates replacing the entire list rather than merging and with different field types like dropdowns and checkboxes requiring specific JSON formatting structures.
Update process
PUT /organizations/{org_id}/runs/{run_id}
Updates properties of an existing process (run). You only need to send the fields you want to change.
Replace {org_id} with your Organization ID and {run_id} with the process run ID.
Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClientContent-Type: application/json
Send a JSON object with only the fields you want to modify. Updatable fields:
name(string): Process name (max 550 characters).summary(string): Process description text.owner_id(string): User ID of the new process owner. Must belong to the organization.starred(boolean): Whether the process is starred/favorited.is_public(boolean): Whether the process is publicly accessible.publicly_hidden_fields(array): Field IDs to hide from public view.users(array of strings): User IDs assigned to the process. Replaces all current user assignees.groups(array of strings): Group IDs assigned to the process. Replaces all current group assignees.prerun(object): Update kick-off form field values. Keys are field timeline IDs, values depend on field type. See Launch process.
Example body:
{ "name": "Onboarding - Globex Corp (Updated)", "summary": "Updated summary notes for this run.", "starred": true, "users": ["user_id_1", "user_id_2"]}const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const runId = 'PROCESS_RUN_ID_TO_UPDATE';const apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/runs/${runId}`;
const updateData = { name: "JS Updated Process Name", summary: "Adding more details here.", starred: true};
const headers = new Headers();headers.append('Authorization', `Bearer ${accessToken}`);headers.append('Accept', 'application/json');headers.append('X-Tallyfy-Client', 'APIClient');headers.append('Content-Type', 'application/json');
fetch(apiUrl, { method: 'PUT', headers: headers, body: JSON.stringify(updateData)}).then(response => { return response.json().then(data => { if (!response.ok) { console.error(`Failed to update process ${runId}:`, data); throw new Error(`HTTP error! status: ${response.status}`); } return data; });}).then(data => { console.log(`Successfully updated process ${runId}:`); console.log(JSON.stringify(data, null, 2));}).catch(error => { console.error(`Error updating process ${runId}:`, 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')run_id = 'PROCESS_RUN_ID_TO_UPDATE'api_url = f'https://go.tallyfy.com/api/organizations/{org_id}/runs/{run_id}'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient', 'Content-Type': 'application/json'}
# Note: Sending 'users' or 'groups' replaces all existing assignees of that type.update_payload = { 'name': 'Python Updated Process Name', 'summary': 'Updated via Python requests.', 'starred': True}
response = Nonetry: response = requests.put(api_url, headers=headers, json=update_payload) response.raise_for_status()
updated_process = response.json() print(f'Successfully updated process {run_id}:') print(json.dumps(updated_process, indent=4))
except requests.exceptions.HTTPError as http_err: print(f"HTTP error updating process {run_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 process {run_id}: {req_err}")except json.JSONDecodeError: print(f"Failed to decode JSON response for process {run_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 UpdateProcess { 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 runId = "PROCESS_RUN_ID_TO_UPDATE"; String apiUrl = String.format("https://go.tallyfy.com/api/organizations/%s/runs/%s", orgId, runId);
// Use Jackson or Gson for production payloads String jsonPayload = "{\"name\": \"Java Updated Run Name\", \"summary\": \"Updated summary.\"}";
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") .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString(jsonPayload)) .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { System.out.println("Successfully updated process " + runId + ":"); System.out.println(response.body()); } else { System.err.println("Failed to update process " + runId + ". Status: " + response.statusCode()); System.err.println("Response: " + response.body()); } } catch (IOException | InterruptedException e) { System.err.println("Request failed: " + e.getMessage()); Thread.currentThread().interrupt(); } }}package main
import ( "bytes" "encoding/json" "fmt" "io" "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" } runId := "PROCESS_RUN_ID_TO_UPDATE" apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/runs/%s", orgId, runId)
updateData := map[string]interface{}{ "name": "Go Updated Process", "summary": "Updated via Go client", }
jsonData, err := json.Marshal(updateData) if err != nil { fmt.Printf("Error marshalling JSON: %v\n", err) return }
client := &http.Client{Timeout: 15 * time.Second} req, err := http.NewRequest(http.MethodPut, apiUrl, bytes.NewBuffer(jsonData)) 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") req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req) if err != nil { fmt.Printf("Error executing request: %v\n", err) return } defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading response body: %v\n", err) return }
if resp.StatusCode != http.StatusOK { fmt.Printf("Failed to update process %s. Status: %d\nBody: %s\n", runId, resp.StatusCode, string(body)) return }
fmt.Printf("Successfully updated process %s:\n", runId) var prettyJSON bytes.Buffer if err := json.Indent(&prettyJSON, body, "", " "); err == nil { fmt.Println(prettyJSON.String()) } else { fmt.Println(string(body)) }}#include <iostream>#include <string>#include <cpprest/http_client.h>#include <cpprest/json.h>
using namespace web;using namespace web::http;using namespace web::http::client;using namespace web::json;
pplx::task<void> UpdateTallyfyProcess(const utility::string_t& runId, const value& updatePayload){ 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("/runs/") + runId;
http_client client(apiUrl); http_request request(methods::PUT);
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")); request.headers().set_content_type(U("application/json")); request.set_body(updatePayload);
return client.request(request).then([runId](http_response response) { utility::string_t runIdW = runId; return response.extract_json().then([response, runIdW](pplx::task<value> task) { try { value const & body = task.get(); if (response.status_code() == status_codes::OK) { std::wcout << L"Successfully updated process " << runIdW << L":\n" << body.serialize() << std::endl; } else { std::wcerr << L"Failed to update process " << runIdW << L". Status: " << response.status_code() << L"\nResponse: " << body.serialize() << std::endl; } } catch (const http_exception& e) { std::wcerr << L"HTTP exception during update process: " << e.what() << std::endl; } catch (const std::exception& e) { std::wcerr << L"Exception during update process response handling: " << e.what() << std::endl; } }); });}
int main() { try { value payload = value::object(); payload[U("name")] = value::string(U("C++ Updated Process Name")); payload[U("summary")] = value::string(U("Updated via C++")); payload[U("starred")] = value::boolean(true);
UpdateTallyfyProcess(U("PROCESS_RUN_ID_TO_UPDATE"), payload).wait(); } catch (const std::exception &e) { std::cerr << "Error in main: " << e.what() << std::endl; } return 0;}// Requires C++ REST SDK (Casablanca)using System;using System.Collections.Generic;using System.Net.Http;using System.Net.Http.Headers;using System.Text;using System.Text.Json;using System.Text.Json.Serialization; // For JsonIgnoreConditionusing System.Threading.Tasks;
public class TallyfyProcessUpdater{ private static readonly HttpClient client = new HttpClient();
public class ProcessUpdatePayload { [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Name { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Summary { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string OwnerId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? Starred { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? IsPublic { get; set; }
// Sending Users or Groups replaces all existing assignees of that type. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List<string> Users { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List<string> Groups { get; set; } }
public static async Task UpdateProcessAsync(string runId, ProcessUpdatePayload payload) { 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}/runs/{runId}";
try { using var request = new HttpRequestMessage(HttpMethod.Put, apiUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Add("X-Tallyfy-Client", "APIClient");
// Serialize payload, ignoring nulls var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; string jsonPayload = JsonSerializer.Serialize(payload, options); request.Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.SendAsync(request); string responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) // Expect 200 OK { Console.WriteLine($"Successfully updated process {runId}:"); try { using var doc = JsonDocument.Parse(responseBody); Console.WriteLine(JsonSerializer.Serialize(doc.RootElement, new JsonSerializerOptions { WriteIndented = true })); } catch (JsonException) { Console.WriteLine(responseBody); } } else { Console.WriteLine($"Failed to update process {runId}. Status: {response.StatusCode}"); Console.WriteLine($"Response: {responseBody}"); } } catch (HttpRequestException e) { Console.WriteLine($"Request Exception updating process {runId}: {e.Message}"); } catch (JsonException jsonEx) { Console.WriteLine($"JSON Serialization Error: {jsonEx.Message}"); } catch (Exception ex) { Console.WriteLine($"An unexpected error occurred: {ex.Message}"); } }
// Example Usage: // static async Task Main(string[] args) // { // var processUpdate = new ProcessUpdatePayload { // Summary = "Updated C# summary.", // Starred = true // }; // await UpdateProcessAsync("PROCESS_RUN_ID_TO_UPDATE", processUpdate); // }}Returns 200 OK with the full updated process wrapped in a data object.
{ "data": { "id": "PROCESS_RUN_ID_TO_UPDATE", "checklist_id": "template_timeline_id", "checklist_title": "Onboarding Template", "name": "Onboarding - Globex Corp (Updated)", "summary": "Updated summary notes for this run.", "status": "active", "progress": 25, "owner_id": "user_id", "starred": true, "is_public": false, "users": [], "groups": [], "created_at": "2025-01-15T10:00:00Z", "last_updated": "2025-01-20T14:30:00Z" }}If the run ID isn’t found, you don’t have permission, or the request body is invalid, you’ll get a 404, 403, or 422 error response.
Tallyfy’s API lets you update an existing template by sending a PUT request with a required title field and optional properties like guidance text and owner and webhook URL and folder assignment and public visibility and auto-naming format and user/group lists where array fields fully replace existing lists rather than appending to them.
Edit Processes > Edit tasks and process properties
Tallyfy lets you modify a running process without restarting it by opening the process from Tracker view and clicking the Settings gear icon to rename it and reassign the owner and add notes or export data.
Code Samples > Managing processes (Runs)
The Tallyfy API manages processes (called “runs”) through org-scoped endpoints that cover launching from templates or as empty containers and listing and filtering and fetching details and updating and archiving and restoring and permanently deleting processes along with retrieving activity feeds for audit trails.
Was this helpful?
About Tallyfy
- 2025 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks