Get & use a personal access token
The primary way to authenticate with the Tallyfy API is using your personal access_token
. This token acts on your behalf, granting API requests the same permissions you have within Tallyfy. Simple and straightforward - no OAuth dance required for basic usage.
- Log in to your Tallyfy account at https://go.tallyfy.com/ ↗.
- Navigate to Settings (usually via your profile picture or menu).
- Go to the Integrations section.
- Select REST API.
- Your personal
access_token
will be displayed here. Copy it securely.
Token Invalidation on Logout
Important: Your personal access token is automatically invalidated and regenerated every time you log out of Tallyfy. This is a security feature that can impact your integrations.
What causes token invalidation:
- Manual logout from the web interface
- Automatic session timeout after inactivity
- Browser clearing cookies/sessions
- Switching between multiple Tallyfy organizations
- Password reset operations
Impact on automations:
- All API calls using the old token will return 401/403 errors
- Automations will stop working immediately
- You’ll need to manually update the token in all integrations
Best practices for stable API access:
- Dedicated service accounts - Create a specific user for API integrations who never logs out
- Error handling - Implement 401/403 detection with alerts for token refresh
- Token monitoring - Track token validity and alert on unexpected changes
- Document dependencies - Keep a list of all systems using each token
- Consider OAuth flow - For production systems, use OAuth with refresh tokens
- Enterprise options - Contact support about application tokens that don’t expire on logout
Once you have your token, you need to include it in the Authorization
header of every API request you make. The format is Bearer {your_access_token}
.
You also need to include two other standard headers:
Accept: application/json
(Tells the API you expect a JSON response)X-Tallyfy-Client: APIClient
(Identifies the request as coming from a custom API client - don’t forget this header or you’ll get 401s)
Here’s how to add these headers in different languages:
const accessToken = 'YOUR_PERSONAL_ACCESS_TOKEN';const orgId = 'YOUR_ORGANIZATION_ID';const apiUrl = `https://go.tallyfy.com/api/organizations/${orgId}/me/tasks`; // Example endpoint
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) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json();}).then(data => { console.log(data);}).catch(error => { console.error('Error fetching data:', error);});
import requestsimport json
access_token = 'YOUR_PERSONAL_ACCESS_TOKEN'org_id = 'YOUR_ORGANIZATION_ID'api_url = f'https://go.tallyfy.com/api/organizations/{org_id}/me/tasks' # Example endpoint
headers = { 'Authorization': f'Bearer {access_token}', 'Accept': 'application/json', 'X-Tallyfy-Client': 'APIClient'}
try: response = requests.get(api_url, headers=headers) response.raise_for_status() # Raises an HTTPError for bad responses (4XX or 5XX)
# Process the JSON data tasks = response.json() print(json.dumps(tasks, indent=4))
except requests.exceptions.RequestException as e: print(f"Request failed: {e}")except json.JSONDecodeError: print("Failed to decode JSON response")
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 TallyfyApiClient {
public static void main(String[] args) { String accessToken = "YOUR_PERSONAL_ACCESS_TOKEN"; String orgId = "YOUR_ORGANIZATION_ID"; String apiUrl = "https://go.tallyfy.com/api/organizations/" + orgId + "/me/tasks"; // Example endpoint
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() // Default method is GET .build();
try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) { System.out.println("Response Body:"); System.out.println(response.body()); // Consider using a JSON library (like Jackson or Gson) to parse the body } else { System.err.println("Request failed with status code: " + response.statusCode()); System.err.println("Response Body: " + response.body()); } } catch (IOException | InterruptedException e) { System.err.println("Request failed: " + e.getMessage()); Thread.currentThread().interrupt(); // Restore interrupted status } }}
package main
import ( "fmt" "io/ioutil" "net/http" "time")
func main() { accessToken := "YOUR_PERSONAL_ACCESS_TOKEN" orgId := "YOUR_ORGANIZATION_ID" apiUrl := fmt.Sprintf("https://go.tallyfy.com/api/organizations/%s/me/tasks", orgId) // Example endpoint
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 body: %v\n", err) return }
if resp.StatusCode != http.StatusOK { fmt.Printf("Request failed with status code: %d\n", resp.StatusCode) fmt.Printf("Response Body: %s\n", string(body)) return }
fmt.Println("Response Body:") fmt.Println(string(body)) // Consider using encoding/json to unmarshal the body into a struct}
#include <iostream>#include <string>#include <vector>#include <cpprest/http_client.h>#include <cpprest/filestream.h>
using namespace web;using namespace web::http;using namespace web::http::client;
pplx::task<void> GetMyTasks(){ 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("/me/tasks");
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([](http_response response) { if (response.status_code() == status_codes::OK) { return response.extract_json(); } else { // Handle error return response.extract_string().then([](utility::string_t body) { std::wcerr << L"Error response body: " << body << std::endl; return pplx::task_from_result(json::value::null()); }); } }).then([](pplx::task<json::value> previousTask) { try { json::value const & v = previousTask.get(); if (!v.is_null()) { std::wcout << L"Success:\n" << v.serialize() << std::endl; } else { std::wcerr << L"Error fetching tasks." << std::endl; } } catch (const http_exception& e) { std::wcerr << L"HTTP Exception caught: " << e.what() << std::endl; } catch (const std::exception& e) { std::wcerr << L"Exception caught: " << e.what() << std::endl; } catch (...) { std::wcerr << L"Unknown exception caught" << std::endl; } });}
int main(){ try { GetMyTasks().wait(); } catch (const std::exception &e) { std::wcerr << L"Error in main: " << e.what() << std::endl; } catch (...) { std::wcerr << L"Unknown exception caught in main" << std::endl; } return 0;}// Note: Requires C++ REST SDK (Casablanca). Ensure proper setup and linking.
using System;using System.Net.Http;using System.Net.Http.Headers;using System.Threading.Tasks;
public class TallyfyApiRequest{ private static readonly HttpClient client = new HttpClient();
public static async Task GetMyTasks() { var accessToken = "YOUR_PERSONAL_ACCESS_TOKEN"; var orgId = "YOUR_ORGANIZATION_ID"; var apiUrl = $"https://go.tallyfy.com/api/organizations/{orgId}/me/tasks"; // Example endpoint
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("Success:"); Console.WriteLine(responseBody); // TODO: Deserialize JSON (e.g., using System.Text.Json or Newtonsoft.Json) } else { Console.WriteLine($"Error: {response.StatusCode}"); Console.WriteLine(responseBody); } } catch (HttpRequestException e) { Console.WriteLine($"Request Exception: {e.Message}"); } }
// Example usage (e.g., in a Main method) // static async Task Main(string[] args) // { // await GetMyTasks(); // }}
Remember to replace YOUR_PERSONAL_ACCESS_TOKEN
and YOUR_ORGANIZATION_ID
with your actual Tallyfy values. (And please don’t copy-paste these placeholders into production - we’ve all been there, but it’s never fun to debug.)
Open Api > Integrate with Tallyfy using the API
Code Samples > Authentication methods
- 2025 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks