Refuelings
Role names and
user_group_idvalues are listed in User groups.
Fuel uplifts, what they cost, and the excise duty inside that cost.
Access: every endpoint below requires user_group_id ≤ 130 (Financial Manager and above) and a non-free company plan. Anything else receives 404. All results are scoped to the caller's own company.
Derived values are server-side. quantity_l, net_amount, vat_amount, total_amount, excise_amount and status are computed on save and ignored if posted. Do not recompute them in a client: the unit conversion needs the fuel's density, and two implementations of the same tax arithmetic will eventually disagree.
unit_price is the pump price — excluding VAT, including excise duty. excise_amount is therefore a component of net_amount, never a line added on top of it. net_amount + vat_amount == total_amount always holds.
Worked example — 1,000 l of AVGAS 100LL at €2.10, VAT 21%, Spanish duty €0.40620/l:
quantity_l
already litres
1000.000
net_amount
unit_price × quantity
2100.00
excise_amount
quantity_l × rate
406.20
vat_amount
net_amount × vat_rate / 100
441.00
total_amount
net_amount + vat_amount
2541.00
The excise is inside the net, so it does not appear in the total. A client that adds excise_amount to total_amount double-counts the duty. The same uplift sent as 720 with unit: "kgs" yields identical figures, because AVGAS is 0.72 kg/l — but only once the aircraft has a fuel_type; without one, quantity_l is null and no duty is derived.
List Refuelings
GET /manager/refuelings/index.json
Returns a page of uplifts plus totals and a per-airport rollup. The totals and the rollup cover the whole filtered set, not the current page.
Query Parameters
from
date
YYYY-MM-DD, inclusive
to
date
YYYY-MM-DD, inclusive
aircraft_id
number
airport
string
Airport ident, exact match
supplier
string
Exact match
fuel_type
string
AVGAS100LL, JETA1, JETA, MOGAS, SAF, OTHER
status
string
PENDING (needs pricing) or PRICED
page
number
Default 1
limit
number
Default 25, maximum 1000
Response
totals and locations carry one entry per currency. Amounts are never converted between currencies — there is no exchange rate source, and a fabricated rate inside a tax figure would be worse than separate subtotals.
quantity_l is null when the quantity cannot be converted: a kgs or lbs uplift on an aircraft with no fuel_type. Such a row gets no automatic duty either. Fix it by setting fuel_type on the aircraft.
Form Options
GET /manager/refuelings/form_options.json
Aircraft, and the supplier and airport values already in use, for filters and the add form.
Create or Update a Refueling
POST /manager/refuelings/edit.json
Form-encoded. Include data[Refueling][id] to update; omit it to create.
aircraft_id
Required on create. Must belong to your company.
date
YYYY-MM-DD. Defaults to today on create.
airport
Airport ident
supplier
quantity
Required, greater than zero, in the aircraft's own unit
currency
Defaults to the company currency on create
unit_price
Ex-VAT, duty-inclusive
vat_rate
Percentage, e.g. 21.0
excise_amount
Omit to take it from the duty rate table. Rejected if larger than the net amount.
excise_recoverable
1 or 0
excise_reclaimed_on
YYYY-MM-DD, for tracking what you have already filed
invoice_ref
notes
fuel_type and unit are not accepted. Both are inherited from the aircraft and snapshotted onto the row when it is created, so that a fleet's units are stated in exactly one place and changing an aircraft later never re-interprets historic quantities.
Bulk Price
POST /manager/refuelings/bulk_price.json
Applies one invoice's figures to many uplifts at once.
data[Refueling][ids][]
Repeat per refuelling. Required.
data[Refueling][unit_price]
data[Refueling][vat_rate]
data[Refueling][supplier]
data[Refueling][invoice_ref]
data[Refueling][currency]
Fields you omit are left unchanged on every row. Each row is saved individually, so litres, VAT, duty and status are derived exactly as on a single edit.
Delete a Refueling
POST /manager/refuelings/delete.json
Send data[Refueling][id].
A refuelling seeded from a flight will reappear the next time that flight is saved — the flight still says fuel went in. To remove it permanently, clear the fuel quantity on the flight instead.
Duty Rates
Excise is a fixed amount per litre set by the country of purchase, never a percentage. Rates are effective-dated, and saving one does not restate the duty already stored on past uplifts.
GET /manager/refuelings/rates.json
POST /manager/refuelings/rate_edit.json
country
ISO code of the airport's country. Blank = company-wide fallback.
fuel_type
Required
amount_per_litre
Required, not negative
currency
valid_from
Required, YYYY-MM-DD
valid_to
Blank = open-ended
Lookup order: a rate for the airport's own country wins over the company-wide fallback; among equally specific rates, the most recently effective one wins.
POST /manager/refuelings/rate_delete.json
Send data[FuelDutyRate][id].
Excise Reclaim Report
GET /manager/refuelings/reclaim.json
How much of the excise duty paid in a period is recoverable.
Excise is recoverable by use, not by purchase. The duty each aircraft paid is apportioned by that aircraft's share of block time flown on flight types where fuel_duty_recoverable = 1:
Both sides of the ratio are per aircraft, so the aircraft's own consumption rate cancels out — no rate weighting is applied or needed.
Only LANDED flights count. A flight with no flight type counts as qualifying, matching the column default: treating unknown as non-qualifying would silently shrink a claim, which is the more damaging of the two mistakes.
Query Parameters
from
date
YYYY-MM-DD, inclusive. Defaults to 1 January of the current year.
to
date
YYYY-MM-DD, inclusive. Defaults to today.
Response
aircraft is sorted by reclaimable descending, and only includes aircraft that bought fuel in the period.
duty_excluded
Duty on uplifts with excise_recoverable = 0. Reported separately so a deliberate exclusion stays distinguishable from a missing figure.
share
qualifying_seconds / total_seconds, or null when the aircraft did not fly.
no_hours
The aircraft bought fuel but flew nothing in the period, so nothing is reclaimable against it. reclaimable is 0, never a division by zero.
vat
Reference only. Never part of reclaimable — VAT is recovered through a different mechanism entirely.
warnings counts everything that makes the figure understate the real claim. Each entry can only make the reclaim smaller, never larger:
unpriced
Refuelings still PENDING, so they carry no duty
missing_litres
quantity_l is null — a mass uplift on an aircraft with no fuel_type
missing_duty
Priced and converted, but no excise_amount — usually no matching duty rate
missing_airport
No airport, so no country to match a rate against
Consumption Cross-check
GET /manager/refuelings/consumption.json
Two data-quality checks: uplift rate against each aircraft's own baseline, and fuel bought against fuel billed on.
Query Parameters
from
date
Defaults to 1 January of the current year
to
date
Defaults to today
The baseline is the twelve months immediately before from, so the period under examination never contributes to the figure it is judged against.
flagged is |variance| >= threshold, but only for aircraft with at least 10 block hours in the period — below that the ratio is dominated by whether a fill happened to land inside the window. comparable is false when there are too few hours or no baseline.
The threshold of 0.25 was measured against real fleet data rather than picked: at 0.15 it flagged seven aircraft in eleven, which nobody reads.
In billing, difference and recovery are null when mixed_currency is true — there is no exchange rate available to compare purchases across currencies. billed sums user_bills.fuel for flights of that aircraft in the period and has no currency dimension of its own.
Import a Fuel Card Statement
POST /manager/refuelings/import.json
JSON body, not form-encoded:
Rows are expected to be already parsed and column-mapped — supplier statements share no common format, so the mapping belongs where a human can see the file rather than in a server-side guess. Numbers must be normalised to a plain decimal point before sending; 120,50 will be rejected as a bad quantity.
aircraft
Registration. Matched ignoring case and separators, so EC-KMH, ECKMH and ec kmh all resolve.
aircraft_id
Alternative to aircraft, and takes precedence.
date
Anything strtotime understands; stored as Y-m-d.
quantity
Required, greater than zero, in the aircraft's own unit.
airport, supplier, unit_price, vat_rate, excise_amount, currency, invoice_ref
Optional
fuel_type and unit are inherited from the aircraft, exactly as on every other creation path. Rows are created with source: "IMPORT".
Maximum 2000 rows per request.
Response
A row matching an existing refueling on aircraft + date + quantity + invoice reference is counted in duplicates and skipped, so re-importing the same statement never doubles a fuel bill.
reason is one of unknown_aircraft, bad_date, bad_quantity or save_failed. Bad rows are reported with their line number rather than silently dropped; the rest of the import still applies.
Last updated