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.
Create a template
Send a POST request to create a new template (called a “checklist” in the API) inside an organization. The response returns the newly created template with a 201 Created status.
POST https://go.tallyfy.com/api/organizations/{org}/checklists| Parameter | Type | Description |
|---|---|---|
org | string | Required. The organization ID. |
Pass a JSON object with the template properties you want to set.
| Parameter | Type | Description |
|---|---|---|
title | string | Required. Template title (max 250 characters). |
type | string | Required. One of procedure, form, or document. |
summary | string | Short description (max 2000 characters). |
owner_id | integer | Member ID of the template owner. Must belong to the organization. |
user_id | integer | Member ID of the template starter. Must belong to the organization. |
webhook | string | URL for webhook notifications on template events. Must be a valid URL. |
explanation_video | string | URL of a video explaining the template. Must be a valid URL. |
starred | boolean | Whether to star the template. |
guidance | string | Instructions or guidance for using the template. |
icon | string | Icon name to associate with the template. |
is_public | boolean | Make the template publicly visible in the library. |
is_featured | boolean | Feature the template in the public library. |
public_cover | string | Cover image URL for the public library listing. |
folder_id | string | ID of an existing folder to place the template in. |
default_process_name_format | string | Format string for auto-naming processes launched from this template. |
is_public_kickoff | boolean | Make the kick-off form publicly accessible. |
auto_naming | boolean | Turn on automatic process naming using default_process_name_format. |
dual_version_enabled | boolean | Enable dual-version (draft/published) mode. |
users | array | Array of member IDs who get default access to this template. |
groups | array | Array of group IDs that get default access to this template. |
prerun | array | Array of objects defining kick-off form fields. Each needs label, field_type, and required at minimum. |
folderize_process | boolean | Auto-create a folder for processes launched from this template. |
tag_process | boolean | Auto-tag processes launched from this template. |
allow_launcher_change_name | boolean | Let the launcher override the default process name. Only applies when auto_naming is off. |
can_add_oot | boolean | Allow adding one-off tasks to processes from this template. |
const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID'; // Replace with actual Org IDconst apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/checklists`;
const templateData = { title: "New JS API Template", // Required type: "procedure", // Required: "procedure", "form", or "document" summary: "Template created via Fetch API.", owner_id: 12345 // Optional: owner member ID};
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: 'POST', headers: headers, body: JSON.stringify(templateData)}).then(response => { return response.json().then(data => { if (!response.ok) { console.error("Failed to create template:", data); throw new Error(`HTTP error! status: ${response.status}`); } // Expect 201 Created console.log(`Template created. Status: ${response.status}`); return data; });}).then(data => { console.log('Successfully created template:'); console.log(JSON.stringify(data, null, 2)); // Use data.data.id to get the new template ID}).catch(error => { console.error('Error creating template:', 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') # Replace with actual Org IDapi_url = f'https://go.tallyfy.com/api/organizations/{org_id}/checklists'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient', 'Content-Type': 'application/json'}
template_payload = { 'title': 'New Python API Template', # Required 'type': 'procedure', # Required: "procedure", "form", or "document" 'summary': 'Template created via Python requests.', 'owner_id': 12345, # Optional: owner member ID}
response = Nonetry: response = requests.post(api_url, headers=headers, json=template_payload) response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)
created_template = response.json() print('Successfully created template:') print(json.dumps(created_template, indent=4)) # new_template_id = created_template.get('data', {}).get('id')
except requests.exceptions.HTTPError as http_err: error_details = "" try: if response is not None: error_details = response.json() except json.JSONDecodeError: if response is not None: error_details = response.text print(f"HTTP error occurred creating template: {http_err}") print(f"Response Body: {error_details}")except requests.exceptions.RequestException as req_err: print(f"Request failed creating template: {req_err}")except json.JSONDecodeError: print("Failed to decode successful JSON response after creating template") if response is not None: print(f"Response Text: {response.text}")except Exception as err: print(f"An unexpected error occurred: {err}")import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.io.IOException;import java.time.Duration;// Requires a JSON library like Jackson or Gson// import com.fasterxml.jackson.databind.ObjectMapper;// import java.util.Map;// import java.util.HashMap;
public class CreateTemplate { 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"); // Replace with actual Org ID String apiUrl = "https://go.tallyfy.com/api/organizations/" + orgId + "/checklists";
// --- Payload Construction --- // Using Jackson/Gson recommended: /* ObjectMapper mapper = new ObjectMapper(); Map<String, Object> templateData = new HashMap<>(); templateData.put("title", "Java API Template"); // Required templateData.put("summary", "Created via Java"); templateData.put("type", "procedure"); String jsonPayload; try { jsonPayload = mapper.writeValueAsString(templateData); } catch (Exception e) { System.err.println("Failed to serialize JSON: " + e.getMessage()); return; } */ // Simple manual JSON string: String jsonPayload = "{\"title\": \"Java API Template Simple\", \"type\": \"procedure\"}"; // Minimal payload // --- End Payload ---
HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build();
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") .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 201) { // 201 Created on success System.out.println("Successfully created template:"); System.out.println(response.body()); // TODO: Consider parsing the JSON response // String templateId = objectMapper.readTree(response.body()).path("data").path("id").asText(); } else { System.err.println("Failed to create template. Status: " + response.statusCode()); System.err.println("Response Body: " + response.body()); } } catch (IOException | InterruptedException e) { System.err.println("Request failed: " + e.getMessage()); Thread.currentThread().interrupt(); } catch (Exception e) { System.err.println("An unexpected error occurred: " + e.getMessage()); e.printStackTrace(); } }}package main
import ( "bytes" "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" } // Replace with actual Org ID apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/checklists", orgId)
templateData := map[string]interface{}{ "title": "Go API Template", // Required "summary": "Created via Go net/http", "type": "procedure", // "owner_id": 12345, // "users": []int{1001}, }
jsonData, err := json.Marshal(templateData) if err != nil { fmt.Printf("Error marshalling JSON: %v\n", err) return }
client := &http.Client{Timeout: 15 * time.Second} req, err := http.NewRequest(http.MethodPost, apiUrl, bytes.NewBuffer(jsonData)) if err != nil { fmt.Printf("Error creating create template 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 create template request: %v\n", err) return } defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading create template response body: %v\n", err) return }
if resp.StatusCode != http.StatusCreated { fmt.Printf("Failed to create template. Status: %d\nBody: %s\n", resp.StatusCode, string(body)) return }
fmt.Println("Successfully created template:") // Pretty print JSON response var prettyJSON bytes.Buffer if err := json.Indent(&prettyJSON, body, "", " "); err == nil { fmt.Println(prettyJSON.String()) } else { fmt.Println(string(body)) } // TODO: Unmarshal JSON to get the new template ID etc.}#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> CreateTallyfyTemplate(const value& templatePayload){ utility::string_t accessToken = U("YOUR_PERSONAL_ACCESS_TOKEN"); utility::string_t orgId = U("YOUR_ORGANIZATION_ID"); // Replace with actual Org ID utility::string_t apiUrl = U("https://go.tallyfy.com/api/organizations/") + orgId + U("/checklists");
http_client client(apiUrl); http_request request(methods::POST);
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(templatePayload);
return client.request(request).then([](http_response response) { return response.extract_json().then([response](pplx::task<value> task) { try { value const & body = task.get(); if (response.status_code() == status_codes::Created) { std::wcout << L"Successfully created template:\n" << body.serialize() << std::endl; // Extract new template ID: body[U("data")][U("id")].as_string(); } else { std::wcerr << L"Failed to create template. Status: " << response.status_code() << L"\nResponse: " << body.serialize() << std::endl; } } catch (const http_exception& e) { std::wcerr << L"HTTP exception during create template: " << e.what() << std::endl; } catch (const std::exception& e) { std::wcerr << L"Exception during create template response handling: " << e.what() << std::endl; } }); });}
int main() { try { value payload = value::object(); payload[U("title")] = value::string(U("C++ API Template")); // Required payload[U("summary")] = value::string(U("Created via C++ REST SDK")); payload[U("type")] = value::string(U("procedure")); // payload[U("owner_id")] = value::number(12345);
CreateTallyfyTemplate(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 TallyfyTemplateCreator{ private static readonly HttpClient client = new HttpClient();
public class TemplatePayload { public string Title { get; set; } // Required
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Summary { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? OwnerId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Type { get; set; } // e.g., "procedure"
// Add other properties from the Body Parameters table as needed // [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // public List<int> Users { get; set; } // ... etc ... }
public static async Task CreateTemplateAsync(TemplatePayload payload) { var accessToken = Environment.GetEnvironmentVariable("TALLYFY_ACCESS_TOKEN") ?? "YOUR_PERSONAL_ACCESS_TOKEN"; var orgId = Environment.GetEnvironmentVariable("TALLYFY_ORG_ID") ?? "YOUR_ORGANIZATION_ID"; // Replace with actual Org ID var apiUrl = $"https://go.tallyfy.com/api/organizations/{orgId}/checklists";
if (string.IsNullOrWhiteSpace(payload?.Title)) { Console.WriteLine("Error: Template Title is required."); return; }
try { using var request = new HttpRequestMessage(HttpMethod.Post, 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, ignore 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 201 Created { Console.WriteLine("Successfully created template:"); try { using var doc = JsonDocument.Parse(responseBody); Console.WriteLine(JsonSerializer.Serialize(doc.RootElement, new JsonSerializerOptions { WriteIndented = true })); // Get template ID: doc.RootElement.GetProperty("data").GetProperty("id").GetString(); } catch (JsonException) { Console.WriteLine(responseBody); } } else { Console.WriteLine($"Failed to create template. Status: {response.StatusCode}"); Console.WriteLine($"Response: {responseBody}"); } } catch (HttpRequestException e) { Console.WriteLine($"Request Exception: {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 newTemplate = new TemplatePayload { // Title = "C# API Template Example", // Summary = "Created from C#", // Type = "procedure" // }; // await CreateTemplateAsync(newTemplate); // }}A successful call returns the full template object wrapped in data:
{ "data": { "id": "b3d9c1a8e7f6...", "increment_id": 42, "title": "New Client Onboarding Template", "summary": "Standard procedure for onboarding new clients.", "starred": false, "webhook": null, "guidance": null, "alias": "new-client-onboarding-template-b3d9c1", "folder_id": null, "prerun": [], "created_by": 123, "owner_id": 12345, "kickoff_title": null, "kickoff_description": null, "started_processes": 0, "created_at": "2025-10-27T10:00:00.000Z", "last_updated": "2025-10-27T10:00:00.000Z", "archived_at": null, "is_public": false, "automated_actions": [], "topic_tags": [], "industry_tags": [], "public_cover": null, "icon": null, "type": "procedure", "steps_count": 0, "is_public_kickoff": false, "default_process_name_format": null, "dual_version_enabled": false, "is_published_state": false, "is_featured": false, "auto_naming": false, "last_updated_by": 123, "status": null, "explanation_video": null, "users": [], "groups": [], "is_pinned": false, "folderize_process": false, "tag_process": false, "allow_launcher_change_name": false, "ko_form_blueprint_id": null, "default_folder": null, "folder_changeable_by_launcher": false, "can_add_oot": false, "kickoff_sharing_user_id": null }} Tallyfy’s Launch Process API endpoint (POST to /organizations/[org_id]/runs) lets you programmatically start a new process from a template by providing a checklist_id along with optional parameters like name and pre-filled kick-off form fields and per-step assignee or deadline overrides.
Tallyfy’s API lets you retrieve a paginated and filterable list of process templates (called “checklists” in the API) for your organization using a GET request with optional query parameters for searching by title and filtering by status or tags or owner along with code examples in JavaScript and Python and Java and Go and C++ and C#.
Tallyfy’s API lets you fetch full details of any process template by its unique ID using a GET request and optionally include related data like steps and tags through query parameters.
Was this helpful?
About Tallyfy
- 2025 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks