BlogDocsToolsPricingPhilosophyAbout Log in Sign up
Guide

API reference

Peil REST API documentation — authentication, export formats and the full endpoint reference.

The Peil API is a REST API. Every endpoint requires authentication via an API key with the right scopes. Use it to export data, log hours, create draft invoices, or connect Peil to your own scripts and AI assistants (MCP).

Authentication

Every API request must carry a valid API key as a bearer token in the Authorization header:

Authorization: Bearer peil_xxxxxxxxxxxxxxxxxxxxxxxx

Requests without a valid key get a 401 Unauthorized response. API keys are personal and tied to your account — don't share them.

Create an API key

Create an API key via Settings → Developer settings in the Peil app (Pro). Give your key a recognizable name (e.g. "My accountant" or "Claude") so you can identify and revoke it later, and optionally set an expiry date — a short lifetime is wise for keys you hand to an AI assistant.

A key is shown in full only once, right after creation — save it afterwards in a password manager or a secured environment variable.

Scopes

Every key has its own set of scopes. Read access is always included; write scopes are chosen explicitly at creation. That way a script or assistant never gets more access than it needs.

Scope What it allows
read Read clients, projects, hours, invoices and the orientation snapshot (always active)
timesheet:write Create, edit and delete time entries
invoices:write Create, edit, delete and archive invoices, and write reminder copy — never sends
clients:write Create, edit and delete clients
invoices:send All client-facing email: send invoices, schedule sends and manual reminders — irreversible, deliberately a separate scope

Missing a scope, and the API responds with 403 and {"code": "INSUFFICIENT_SCOPE"}, naming the missing scope. Draft-first: without invoices:send a key can only create drafts — never send anything to your clients. Every write action by a key is logged; you'll find the per-key activity log in Developer settings.

Base URL

https://api.peil.app/api/v1

Example

A request with curl:

curl -H "Authorization: Bearer peil_xxxxxx" \
  https://api.peil.app/api/v1/export/clients?format=csv

The format parameter accepts csv or json for most export endpoints. Archive exports always return a ZIP file.

Core endpoints

Beyond the exports below, a key with the right scopes reaches these endpoints. Full parameters and response schemas are in the interactive reference at the bottom of this page.

Endpoint Scope What it does
GET /clients read Client list (name → id)
GET /projects read Project list
GET·POST·PUT·DELETE /time_entries read · timesheet:write Read, log, edit and delete hours
POST·PUT·DELETE /clients read · clients:write Read and manage clients
GET /invoices · GET /invoices/unbilled-entries read Invoices and unbilled hours
POST·PUT·DELETE /invoices · /archive invoices:write Create, edit, change status, delete, archive invoices (draft-first without invoices:send)
POST /invoices/from-hours invoices:write Draft invoice from unbilled hours (see below)
PUT /invoices/reminder-settings invoices:write Write reminder copy and schedule
POST /invoices/{id}/send-email · /schedule-send · /send-reminder invoices:send Send an invoice, schedule it, or email a reminder
GET /orientation/snapshot read Compact financial snapshot (see below)

Draft invoice from hours

POST /invoices/from-hours is the API's compound verb: it gathers a client's unbilled billable hours over a period, builds the invoice lines and creates a draft — numbering happens only on send. grouping controls the line layout: summary (one line per description, blended rate), by_project or per_day.

curl -X POST https://api.peil.app/api/v1/invoices/from-hours \
  -H "Authorization: Bearer peil_xxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 12,
    "period_start": "2026-06-01",
    "period_end": "2026-06-30",
    "grouping": "summary"
  }'

The response contains the full draft invoice plus entry_count and total_hours; the hours used are linked to the draft. If there's nothing to invoice, you get 422 with {"code": "NO_UNBILLED_ENTRIES"}.

Orientation snapshot

GET /orientation/snapshot answers "where do I stand?" in a single request: outstanding, overdue (derived from the due date), drafts, invoiced this year, and unbilled hours.

{
  "outstanding": { "count": 2, "total": 2420.0 },
  "overdue":     { "count": 1, "total": 1210.0 },
  "drafts":      { "count": 1, "total": 500.0 },
  "invoiced_ytd": 24000.0,
  "uninvoiced":  { "hours": 12.5, "value": 1125.0 },
  "billable_hours_ytd": 800.0,
  "as_of": "2026-07-14"
}

Limits

Write endpoints are rate-limited per minute: logging hours 60/min, creating invoices 20/min, sending 10/min. Beyond that the API responds 429. Maximum 10 keys per account.

Export formats

The Peil API offers the following export endpoints. All endpoints are GET requests and require authentication.

Endpoint Format Content
/export/clients CSV / JSON Client name, contact details, created date
/export/time-entries CSV / JSON Date, hours, rate, client, project
/export/invoices CSV / JSON Invoice number, amount, status, client
/export/invoices/archive ZIP All PDF invoices
/export/full ZIP All exports above, combined

The full interactive endpoint reference is below. All routes, parameters and response schemas are generated automatically from the live OpenAPI specification.