Archive or delete template
There are two ways to remove a template via the API:
- Archive (soft delete): Hides the template but keeps its data. Processes already launched from it keep running. Archived templates can be restored, and restoring brings back the template’s steps, form fields, automations and folder. If other templates or steps embedded this one in their text, archiving takes those embedded blocks out, and restoring puts them back. Templates archived before mid-September 2026 are the exception: Tallyfy didn’t save a copy of the removed text then, so those embeds need adding again by hand.
- Delete (permanent): Permanently removes the template and its associated data. This can’t be undone. The template must be archived first before it can be permanently deleted.
1. Archive a template
Section titled “1. Archive a template”Endpoint
Section titled “Endpoint”DELETE /organizations/{org_id}/checklists/{checklist_id}
This archives the specified template (soft delete).
Request
Section titled “Request”Replace {org_id} with your Organization ID and {checklist_id} with the template ID.
Headers
Section titled “Headers”Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClient
No request body is needed.
Code samples
Section titled “Code samples”const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const checklistId = 'TEMPLATE_ID_TO_ARCHIVE';const apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/checklists/${checklistId}`;
const headers = new Headers();headers.append('Authorization', `Bearer ${accessToken}`);headers.append('Accept', 'application/json');headers.append('X-Tallyfy-Client', 'APIClient');
fetch(apiUrl, { method: 'DELETE', headers: headers}).then(response => { if (!response.ok) { return response.json().then(errData => { throw new Error(`HTTP error! status: ${response.status}, message: ${JSON.stringify(errData)}`); }).catch(() => { throw new Error(`HTTP error! status: ${response.status}`); }); } console.log(`Successfully archived template ${checklistId}. Status: ${response.status}`); return response.json();}).then(data => { if (data) { console.log('Response:', JSON.stringify(data, null, 2)); }}).catch(error => { console.error('Error archiving template:', error);});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')checklist_id = 'TEMPLATE_ID_TO_ARCHIVE'api_url = f'https://go.tallyfy.com/api/organizations/{org_id}/checklists/{checklist_id}'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient'}
try: response = requests.delete(api_url, headers=headers) response.raise_for_status()
print(f'Successfully archived template {checklist_id}. Status: {response.status_code}') print(json.dumps(response.json(), indent=4))
except requests.exceptions.RequestException as e: print(f"Request failed: {e}") if response is not None: print(f"Response Status: {response.status_code}") try: print(f"Response Body: {response.json()}") except json.JSONDecodeError: print(f"Response Body: {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;import java.time.Duration;
public class ArchiveTemplate {
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 checklistId = "TEMPLATE_ID_TO_ARCHIVE"; String apiUrl = "https://go.tallyfy.com/api/organizations/" + orgId + "/checklists/" + checklistId;
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") .DELETE() .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) { System.out.println("Successfully archived template " + checklistId + ". Status: " + response.statusCode()); if (response.body() != null && !response.body().isEmpty()) { System.out.println("Response Body:"); System.out.println(response.body()); } } else { System.err.println("Failed to archive template. 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 ( "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" } checklistId := "TEMPLATE_ID_TO_ARCHIVE" apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/checklists/%s", orgId, checklistId)
client := &http.Client{Timeout: 15 * time.Second} req, err := http.NewRequest(http.MethodDelete, apiUrl, nil) if err != nil { fmt.Printf("Error creating DELETE 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 DELETE request: %v\n", err) return } defer resp.Body.Close()
body, err := ioutil.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 archive template %s. Status: %d\nBody: %s\n", checklistId, resp.StatusCode, string(body)) return }
fmt.Printf("Successfully archived template %s. Status: %d\n", checklistId, resp.StatusCode) if len(body) > 0 { fmt.Println("Response Body:") fmt.Println(string(body)) }}Response
Section titled “Response”A successful archive returns 200 OK with a confirmation message and deleted_references. That’s a list of the templates and steps whose descriptions had an embed of this template taken out. Each entry has a type (Blueprint for a template, Step for a step), a title and an id. The list is empty when nothing embedded the template.
{ "message": "The Template was deleted, and references were also deleted from:", "deleted_references": []}The message says “deleted”, but this call only archives the template.
Restoring an archived template
Section titled “Restoring an archived template”PUT /organizations/{org_id}/checklists/{checklist_id}/restore
This brings the template back and puts its embeds back into the templates and steps they were taken from. The response returns the template in data, plus two lists in meta:
restored_references- the embeds that went back.unrestored_references- the embeds that couldn’t, each with aresolutionand areason. Most often that’s because the template or step that held the embed was edited or deleted after the archive.
2. Permanently delete a template
Section titled “2. Permanently delete a template”Endpoint
Section titled “Endpoint”DELETE /organizations/{org_id}/checklists/{checklist_id}/delete
Note the extra /delete path segment compared to the archive endpoint.
Request
Section titled “Request”Replace {org_id} and {checklist_id} as appropriate.
Headers
Section titled “Headers”Authorization: Bearer {your_access_token}Accept: application/jsonX-Tallyfy-Client: APIClient
No request body is needed.
Code samples for delete
Section titled “Code samples for delete”const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const checklistId = 'TEMPLATE_ID_TO_DELETE';// Template must already be archived before permanent deletionconst apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/checklists/${checklistId}/delete`;
const headers = new Headers();headers.append('Authorization', `Bearer ${accessToken}`);headers.append('Accept', 'application/json');headers.append('X-Tallyfy-Client', 'APIClient');
fetch(apiUrl, { method: 'DELETE', headers: headers}).then(response => { if (!response.ok) { return response.json() .catch(() => response.text()) .then(errData => { console.error(`Failed to delete template. Status: ${response.status}`, errData); throw new Error(`HTTP error! status: ${response.status}`); }); } console.log(`Successfully deleted template ${checklistId}. Status: ${response.status}`); return response.json();}).then(data => { if (data) { console.log('Response:', JSON.stringify(data, null, 2)); }}).catch(error => { console.error(`Error deleting template ${checklistId}:`, 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')checklist_id = 'TEMPLATE_ID_TO_DELETE'# Template must already be archived before permanent deletionapi_url = f'https://go.tallyfy.com/api/organizations/{org_id}/checklists/{checklist_id}/delete'
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient'}
response = Nonetry: response = requests.delete(api_url, headers=headers) response.raise_for_status()
print(f'Successfully deleted template {checklist_id}. Status: {response.status_code}') print(json.dumps(response.json(), indent=4))
except requests.exceptions.HTTPError as http_err: print(f"HTTP error trying to delete template {checklist_id}: {http_err}") if response is not None: try: print(f"Response Body: {response.json()}") except json.JSONDecodeError: print(f"Response Body: {response.text}")
except requests.exceptions.RequestException as req_err: print(f"Request failed trying to delete template {checklist_id}: {req_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;
public class DeleteTemplate {
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 checklistId = "TEMPLATE_ID_TO_DELETE"; // Template must already be archived before permanent deletion String apiUrl = String.format("https://go.tallyfy.com/api/organizations/%s/checklists/%s/delete", orgId, checklistId);
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") .DELETE() .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) { System.out.println("Successfully deleted template " + checklistId); if (response.body() != null && !response.body().isEmpty()) { System.out.println("Response Body:"); System.out.println(response.body()); } } else { System.err.println("Failed to delete 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(); } }}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" } checklistId := "TEMPLATE_ID_TO_DELETE" // Template must already be archived before permanent deletion apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/checklists/%s/delete", orgId, checklistId)
client := &http.Client{Timeout: 15 * time.Second} req, err := http.NewRequest(http.MethodDelete, apiUrl, nil) if err != nil { fmt.Printf("Error creating DELETE 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 DELETE request: %v\n", err) return } defer resp.Body.Close()
body, err := ioutil.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 delete template %s. Status: %d\nBody: %s\n", checklistId, resp.StatusCode, string(body)) return }
fmt.Printf("Successfully deleted template %s. Status: %d\n", checklistId, resp.StatusCode) if len(body) > 0 { fmt.Println("Response Body:") var prettyJSON bytes.Buffer if json.Indent(&prettyJSON, body, "", " ") == 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;
// Template must already be archived before permanent deletionpplx::task<void> DeleteTallyfyTemplate(const utility::string_t& checklistId){ 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("/checklists/") + checklistId + U("/delete");
http_client client(apiUrl); http_request request(methods::DEL);
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([checklistId](http_response response) { status_code status = response.status_code(); return response.extract_string().then([=](utility::string_t responseBody) { if (status == status_codes::OK) { std::wcout << L"Successfully deleted template " << checklistId << L". Status: " << status << std::endl; if (!responseBody.empty()) { std::wcout << L"Response Body:\n" << responseBody << std::endl; } } else { std::wcerr << L"Failed to delete template " << checklistId << L". Status: " << status << std::endl; std::wcerr << L"Response Body: " << responseBody << std::endl; throw std::runtime_error("Failed to delete template"); } }); });}
int main() { try { DeleteTallyfyTemplate(U("TEMPLATE_ID_TO_DELETE")).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.Threading.Tasks;using System.Text.Json;
public class TallyfyTemplateDeleter{ private static readonly HttpClient client = new HttpClient();
// Template must already be archived before permanent deletion public static async Task DeleteTemplateAsync(string checklistId) { 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}/checklists/{checklistId}/delete";
try { using var request = new HttpRequestMessage(HttpMethod.Delete, apiUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Add("X-Tallyfy-Client", "APIClient");
HttpResponseMessage response = await client.SendAsync(request); string responseBody = await response.Content.ReadAsStringAsync();
if (response.StatusCode == System.Net.HttpStatusCode.OK) { Console.WriteLine($"Successfully deleted template {checklistId}. Status: {response.StatusCode}"); if (!string.IsNullOrWhiteSpace(responseBody)) { 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 delete template {checklistId}. Status: {response.StatusCode}"); Console.WriteLine($"Response: {responseBody}"); } } catch (HttpRequestException e) { Console.WriteLine($"Request exception trying to delete template {checklistId}: {e.Message}"); } }
// Example usage: // static async Task Main(string[] args) // { // await DeleteTemplateAsync("TEMPLATE_TO_DELETE"); // }}Response
Section titled “Response”A successful permanent deletion returns 200 OK. The response body contains a confirmation message and a list of deleted references, in the same shape as the archive response. If the template isn’t archived yet, you’ll get an error - you must archive it first.
Permanent deletion also throws away the saved copies of any embeds that archiving took out, so those embeds can’t be restored after this.
{ "message": "The Template was deleted, and references were also deleted from:", "deleted_references": []}Related articles
Section titled “Related articles”/organizations/[org_id]/tags/[tag_id] permanently removes a…