The Invoicing API
Everything you can do in Invoicing’s screens, a script can do through its API, as you. You need a personal access token for Invoicing.
The address
Section titled “The address”Invoicing’s API address is shown on the API access screen, for example
https://invoicing-api.eddish.app. Every path starts with /api.
Every endpoint, with what it takes and returns, is in the API reference.
The same address also serves an interactive viewer at /scalar, where you can try requests with your
token. The OpenAPI document is at /openapi/v1.json; tools such as Postman or Insomnia can import it.
Authenticating
Section titled “Authenticating”Send your token with each request in the Authorization header:
curl -H "Authorization: Bearer <your token>" https://invoicing-api.eddish.app/api/clientsThe token acts as you, in the account it was made in:
- It can do what your role allows. An Owner’s token can change business details; a Member’s can’t.
- A Read only token can make
GETrequests only. - It needs your seat in Invoicing, and a plan that includes API access.
What comes back
Section titled “What comes back”Every response has the same shape:
{ "success": true, "data": { … }, "error": null }When something goes wrong, success is false and error says what, with a code a script can check
and a message a person can read. A request with mistakes in it also has fieldErrors, by field.
| Status | Code | What it means |
|---|---|---|
401 |
auth.invalid_credential, auth.expired_credential, auth.revoked_credential |
The token isn’t recognised, has expired, or was revoked. |
403 |
auth.read_only_token |
The token can only read. |
403 |
auth.role_not_permitted |
Your role doesn’t allow that. |
403 |
app.no_seat |
You don’t have a seat in Invoicing. |
403 |
auth.api_access_not_in_plan |
The account’s plan doesn’t include API access. |
403 |
auth.not_a_member |
You’re no longer a member of the account. |
409 |
plan.read_only |
The account is over its plan’s limits, so Invoicing is read only until an Owner or Admin sorts that out. |
429 |
rate_limit.exceeded |
Too many requests. Wait the number of seconds in the Retry-After header. |
Rate limits
Section titled “Rate limits”Each token can make a set number of requests in a short time, set by your plan. Every response carries
X-RateLimit-Limit and X-RateLimit-Remaining, so a script can slow down before it’s refused.
Some useful requests
Section titled “Some useful requests”| Request | Does |
|---|---|
GET /api/team/me |
Who the token acts as |
GET /api/clients |
Clients |
GET /api/projects?clientId=… |
A client’s projects |
GET /api/projects/{id}/task-assignments |
The tasks you can log time against on a project |
GET /api/time-entries?from=2026-10-01&to=2026-10-31 |
Time entries in October |
POST /api/time-entries |
Log time: projectId, workTaskId, spentDate, hours, notes, billable |
GET /api/invoices?state=Open |
Invoices sent and not yet paid |
GET /api/invoices/uninvoiced-summary?clientId=… |
A client’s work not yet invoiced |
Dates are yyyy-mm-dd. Ids are the long id values in responses.
Account API keys
Section titled “Account API keys”An Owner or Admin can also make account API keys, in API keys. A key belongs to the account rather than to a person, and reaches only the few endpoints it is given: listing clients, projects and invoices. For anything else, use a personal access token.