Looking for the full interactive reference?

Open API Reference →

Recipe

Accounting export

Export approved flights and invoices on a nightly cron into a generic accounting backend. Suitable when your destination system has a journal-entry API and you control the chart-of-accounts mapping.

Scopes needed

ScopeWhyAlternative if too broad
public.flights:readList approved flights for the export window.None — required.
public.invoices:readPull line-item detail for posting against the GL.Use public.finance:read for summaries only.
public.finance:readPer-period rollups for reconciliation against your books.Skip if your reconciliation is per-invoice.

Data flow

bash
┌───────────────┐     ┌─────────────────┐     ┌────────────────┐
│ Nightly cron  │ ──▶ │ GET flights+inv │ ──▶ │ Map to GL chart│
└───────────────┘     └─────────────────┘     └───────┬────────┘
                                                       │
                                                       ▼
                                            ┌──────────────────────┐
                                            │ POST to your backend │
                                            │ (idempotency-keyed)  │
                                            └──────────┬───────────┘
                                                       │
                                                       ▼
                                            ┌──────────────────────┐
                                            │ Mark exported in DB  │
                                            └──────────────────────┘

Implementation

1. Bootstrap — list the records in the export window:

bash
# List approved flights for the window
curl "https://api.gaflight.io/api/v1/public/flights?status=approved&from=2026-05-01&to=2026-05-31&limit=200" \
  -H "Authorization: Bearer gaf_pk_<token>" \
  -H "X-Org-Id: <org-uuid>"

# Pagination continues with the cursor returned in the response envelope:
# { "data": [...], "cursor": "eyJp..." }

2. Enrich — map invoice line items to your chart of accounts:

js
// Pseudo-code — your service maps GA Flight invoices to your chart-of-accounts.
function toJournalEntry(invoice) {
  return {
    externalId: `gaflight:${invoice.id}`,            // idempotency key
    date: invoice.issuedAt,
    lines: invoice.lineItems.map(line => ({
      account: mapAccount(line.category),               // your mapping
      debit: line.totalCents,
      currency: invoice.currency,
      memo: line.description,
    })),
  };
}

3. Close-loop — reverse the journal entry if the invoice is voided after export:

js
// Webhook handler — fires when an invoice is voided after export.
app.post("/webhooks/gaflight", verifyHmac, (req, res) => {
  const { type, data } = req.body.event;
  if (type === "compliance.updated" && data.kind === "invoice_voided") {
    yourBackend.reverseJournal(`gaflight:${data.invoiceId}`);
  }
  res.status(204).end();
});

Edge cases

  • Voided invoices: subscribe to compliance.updated and reverse the journal entry by idempotency key.
  • Multi-currency: invoice.currency is per-invoice; do not assume a single org currency.
  • FX rate dating: use invoice.issuedAt (not your sync timestamp) as the FX reference date.
  • Refund flow: refunds appear as negative-amount line items, not separate invoices.
  • Period-close lock: after your books close, only post into the next period; bounce older invoices to a manual queue.
  • Pagination cursors: cursors are opaque; do not parse or store them past the run that issued them.
  • Rate limits: cap concurrency at 4 parallel requests; the rate-limit window is 60s.

Going live

  1. Declare the three scopes above on your developer app with ≥40-char justifications each.
  2. Submit your listing for review (see /developers/review-policy).
  3. Publish under your org and share the install URL with customer organizations.
  4. Schedule the cron in your control plane; alert on consecutive failures.
  5. Document the FX rate source and period-lock rule in your customer-facing runbook.

Generic template

This recipe is a generic implementation pattern. No real integration partner is named or endorsed. Substitute your own backend, terminology, and customer fit as appropriate.