Skip to main content

Import data from a CSV file into Float using the API

How to use Float's API to import logged time data from a CSV file

Nermin Music avatar
Written by Nermin Music
Updated over a week ago

Overview:

This guide will walk you through how to use Float's API to import logged time data from a CSV file. This is helpful if you're transitioning from another tool, syncing with offline data, or migrating from manual tracking systems.

While technical expertise isn't needed for following the steps below, it is helpful. This guide covers everything from installing Python to running your first API-powered script.


Step 1: Install Python

Python is a programming language we will use to run the import script.

  1. Click the yellow "Download Python" button for your operating system.

  2. Run the installer:

    • Windows: During installation, make sure to check "Add Python to PATH".

    • Mac: Use the .pkg installer provided.

  3. Once installed, open your terminal:

    • Windows: Open "Command Prompt" or "Windows Terminal"

    • Mac: Use the built-in "Terminal" app

  4. Verify Python is installed by running:

    python3 --version

    You should see a version number like Python 3.12.0


Step 2: Install Required Python Libraries

We need two libraries: pandas for reading CSV files and requests for sending data to the Float API.

In your terminal, run:

pip3 install pandas requests

Step 3: Prepare Your CSV File

Create a CSV file with the following headers:

people_id,project_id,hours,date,task_name

Each row should represent a time entry, for example:

12345,67890,1.5,2025-07-09,Client Meeting 
23456,67890,0.75,2025-07-10,Design Review

Save the file as something like time_entries.csv.


Step 4: Get Your Float API Key

  1. Log in to your Float account as the account owner. Only the account owner can access the API key.

  2. Go to Team Settings > Integrations

  3. Copy the API Key.

Keep this key secret!

You can explore Float's full API documentation here: https://developer.float.com/


Step 5: Copy and Configure the Script

Open any text editor (like Notepad, VS Code, or TextEdit) and paste the following script:

import pandas as pd
import requests
import time
import os

# === CONFIGURATION ===
CSV_FILE = "/mnt/data/testAPIscript.csv"
FLOAT_API_URL = "https://api.float.com/v3/logged-time"
BEARER_TOKEN = "your_float_api_key_here" # ← Replace with your actual API key
DRY_RUN = True # Set to False to actually send data to Float

REQUIRED_COLUMNS = {"people_id", "project_id", "hours", "date", "task_name"}
SUCCESS_LOG = "success.log"
ERROR_LOG = "error.log"

# === HEADERS FOR AUTH ===
headers = {
"Authorization": f"Bearer {BEARER_TOKEN}",
"Content-Type": "application/json",
"User-Agent": "Glenn's People Import Integration (glenn@example.com)"
}

# === Clear previous logs ===
for log_file in [SUCCESS_LOG, ERROR_LOG]:
if os.path.exists(log_file):
os.remove(log_file)

# === DIAGNOSTIC: Column count per line ===
print("πŸ” Inspecting column count per line in the CSV...\n")
with open(CSV_FILE) as f:
for i, line in enumerate(f, 1):
print(f"Line {i}: {len(line.strip().split(','))} columns")

# === READ CSV ===
try:
df = pd.read_csv(CSV_FILE)
except Exception as e:
print(f"❌ Error reading CSV: {e}")
exit(1)

# === VALIDATE HEADER COLUMNS ===
missing_cols = REQUIRED_COLUMNS - set(df.columns)
if missing_cols:
print(f"❌ Missing required columns: {', '.join(missing_cols)}")
exit(1)

# === SEND DATA ===
for index, row in df.iterrows():
row_num = index + 1

# Skip if any required field is missing
if pd.isnull(row["people_id"]) or pd.isnull(row["project_id"]) or pd.isnull(row["hours"]) or pd.isnull(row["date"]):
with open(ERROR_LOG, "a") as elog:
elog.write(f"[Row {row_num}] Skipped (missing required data): {row.to_dict()}\n")
print(f"⚠️ Row {row_num}: Skipped (missing required data)")
continue

# Ensure task_name is a string, even if missing
task_name = "" if pd.isnull(row.get("task_name")) else str(row["task_name"])

# Prepare payload
payload = {
"people_id": int(row["people_id"]),
"project_id": int(row["project_id"]),
"hours": float(row["hours"]),
"date": str(row["date"]),
"task_name": task_name
}

if DRY_RUN:
print(f"[Dry-run] Row {row_num}: {payload}")
else:
try:
response = requests.post(FLOAT_API_URL, json=payload, headers=headers)
error_text = response.text.strip()

if response.status_code in [200, 201]:
with open(SUCCESS_LOG, "a") as slog:
slog.write(f"[Row {row_num}] Success: {payload}\n")
print(f"βœ… Row {row_num}: Success")
else:
with open(ERROR_LOG, "a") as elog:
elog.write(f"[Row {row_num}] Error {response.status_code}: {error_text} | Payload: {payload}\n")
print(f"❌ Row {row_num}: API Error {response.status_code} – {error_text}")
except Exception as e:
with open(ERROR_LOG, "a") as elog:
elog.write(f"[Row {row_num}] Exception: {e} | Payload: {payload}\n")
print(f"❌ Row {row_num}: Exception occurred – {e}")

time.sleep(0.75)

Replace:

  • your_float_api_key_here with your real token.

  • your@email.com with your email

  • Your Name's Float Import Tool with your name

Save the file as import_to_float.py


Step 6: Run the Script

In the terminal:

  1. Navigate to the folder containing your files:

    cd path/to/your/files
  2. Run the script in dry-run mode first:

    python3 import_to_float.py

    You will see what would be sent without actually sending anything.

  3. When ready, open the file and change:

    DRY_RUN = False
  4. Save and re-run:

    python3 import_to_float.py

    Note: Make sure to save import_to_float.py in the same directory as your import files or use the full path here


Step 7: Review the Logs

  • success.log: shows entries that were successfully sent.

  • error.log: shows any failed entries and why they failed.

Example:


Need Help?

If you have questions or need help formatting your CSV, please contact our support team. We’re happy to assist!

Did this answer your question?