Skip to content

Import fuel-card transactions

Fuel-card providers (Rubis, TotalEnergies, Vivo/Shell and others) export transactions with a card or plate number, a station, litres and a price. This recipe turns them into Fleet fuel logs, so fuel cost, consumption and efficiency reports include them.

Scopes: fuel_logs:write, vehicles:read, vendors:write (to create stations).

  1. Match each transaction to a vehicle. Most cards are tied to a plate. Look the vehicle up once and cache the id:

    Terminal window
    curl "https://api.get-fleet.com/v1/vehicles?license_plate=KDA%20123A" -H "Authorization: Bearer $FLEET_API_KEY"

    If your cards are tied to drivers instead, list users and match on employee_id or email, then find their vehicle with GET /v1/vehicle_assignments?driver_id=…&active_at=<transaction time>.

  2. Match the station to a vendor (optional, but it makes vendor reports work). Search with GET /v1/vendors?q=Rubis%20Westlands, and create the vendor once if it doesn’t exist.

  3. Never import a transaction twice. Send the provider’s transaction id as external_id, with external_system naming the provider. Sending the same pair again returns the fuel log already created instead of a duplicate, so you can safely re-run a whole day’s file.

  4. Create the fuel logs in batches of up to 100. A batch is all or nothing, and an Idempotency-Key makes the retry of a timed-out batch safe. Each fuel log then appears in the cost ledger with its VAT and card reference, ready for your ERP.

import os, uuid, requests
API = "https://api.get-fleet.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['FLEET_API_KEY']}"}
def import_batch(transactions, vehicle_ids):
logs = [
{
"vehicle_id": vehicle_ids[t["plate"]],
"date": t["date"], # "2026-11-01"
"quantity": t["litres"], # 45.2
"unit_price": t["price_per_litre"], # "196.50"
"currency": "KES", # optional: defaults to the vehicle's branch currency
"fuel_type": "diesel",
"external_system": "rubis_card",
"external_id": t["transaction_id"],
"receipt_number": t["receipt_number"],
"tax_amount": t.get("vat"), # VAT included in the total, if the statement shows it
"tax_invoice_number": t.get("etims_invoice"),
"payment_method": "fuel_card",
"payment_reference": t["card_last4"],
"location": t["station"],
"odometer_reading": t.get("odometer"),
"is_partial": not t.get("full_tank", True),
}
for t in transactions
if t["plate"] in vehicle_ids
]
for i in range(0, len(logs), 100):
chunk = logs[i : i + 100]
res = requests.post(
f"{API}/fuel_logs/batch",
json={"data": chunk},
headers={**HEADERS, "Idempotency-Key": str(uuid.uuid5(uuid.NAMESPACE_URL, chunk[0]["receipt_number"] + str(len(chunk))))},
timeout=30,
)
if res.status_code == 400:
print("Rejected:", res.json()["errors"]) # fix the data, then re-run
continue
res.raise_for_status()