# 1Tool API

The 1Tool API lets your own software read and change all data of your 1Tool tenant: contacts, projects, quotes, invoices, appointments and much more. This page takes you to your first call in a few minutes. On the left you find every endpoint, ordered by business area.

## Getting started

**Address of the API:** `https://api.1tool.cloud/v1` – protected by a web application firewall. Use it for every new integration; the examples below use the address of the page you are reading.

### 1. Get a token

Every call needs a bearer token. You get one with the email address and password of a 1Tool user:

```bash
curl -X POST https://api.1tool.cloud/v1/auth/user \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"email": "anna.berger@example.at", "password": "…"}'
```

If the user has two-factor authentication turned on, also send `code` with the code from the authenticator app. The response contains the token in `api_token`.

- **A token is valid for one week.** After that, calls answer `401`; sign in again for a new one. Store the token, not the password, and never in a browser or app that customers can read.
- **For a permanent integration**, create a dedicated user with exactly the permissions the integration needs, so you can block it on its own and see in the log what it did.
- **End a token** when you no longer need it: see *Sessions and devices* in the area *Sign-in and account*.

### 2. Make your first call

```bash
curl "https://api.1tool.cloud/v1/contacts?per_page=5" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer <your token>"
```

You see exactly the data this user may also see in 1Tool. Permissions apply to the API just as they do in the app.

### 3. Find the right endpoint

On the left are the business areas, inside them the resources, and below those the individual calls. Search (Ctrl or Cmd + `K`) finds endpoints by name, path or description. For every call you can copy a code sample on the right or try it out directly with your token.

## The areas

- **Sign-in and account** – How users and contacts sign in, obtain tokens, set up two-factor authentication and manage sessions.
- **Contacts** – Customers, prospects, suppliers and people, with their addresses, groups, relations, notes and visits.
- **Sales** – From the lead through the opportunity to the accepted quote.
- **Projects and tasks** – Projects with phases, members and products, plus tasks, boards, checklists and resource planning.
- **Time and staff** – Time tracking, leave, working hours, shifts, job postings and training.
- **Calendar, courses and surveys** – Appointments and invitations, seminars and courses, certificates, room booking and surveys.
- **Finance** – Invoices and dunning, incoming invoices and costs, accounting, banking and budgets.
- **Products, shop and warehouse** – Product catalogue with variants and prices, orders, online shop and warehouse management.
- **Communication** – Email, newsletters, chat, telephony, SMS and notifications.
- **Files and documents** – Files and folders with sharing, PDF and Excel generation, templates and previews.
- **Reporting** – Reports, lists, charts, statistics and dashboard building blocks.
- **Insurance and commissions** – Industry module for insurance brokers: applications, products, lines of business, claims and commission statements.
- **Administration and settings** – Users and permissions, custom fields and forms, workflows, webhooks and tenant settings.
- **Reference data and utilities** – Countries, languages, dial codes, icons, geocoding and quick search.

## Rules that apply to every endpoint

### Headers

| Header | When | Value |
| --- | --- | --- |
| `Authorization` | always, except for sign-in | `Bearer <token>` |
| `Accept` | recommended | `application/json` |
| `X-Tenant` | only for contact sign-ins and public endpoints | the tenant's UUID. Not needed with a user token: the token knows its tenant. |

### Paging through lists

Lists come in pages as `{ "data": [...], "links": {...}, "meta": {...} }`. Follow `links.next` until it is empty.

- `per_page` sets the page size, at most **1000**. Larger values are cut to 1000 without an error; the size actually used is in `meta.per_page`, the total in `meta.total`.
- For large tables, page with `sort=id&filter[id_after]=<last id>` instead of high page numbers. Many large pages in a row are rate-limited per tenant.
- `skip_total=1` skips counting all matches when you do not need the total.

### Filtering

Filters are written `filter[<name>]=<value>`. The filters an endpoint knows are listed with its parameters; an unknown filter is rejected with an error that names the allowed ones. Separate several values with commas: `filter[id]=1,2,3`.

### Sorting

`sort=<column>` ascending, `sort=-<column>` descending. **Careful:** an unknown sort column is not rejected: the list comes back in its default order, and the response header `X-Ignored-Sort` names the column that was ignored. Check the name against the list on the endpoint.

### Loading related data

`include=contactGroups,assignedUsers` loads related records in the same response. The allowed names are listed with the endpoint's `include` parameter.

### Dates and times

Dates are written as `Y-m-d`, date and time as `Y-m-d H:i:s`, **without a time zone**: they are local time in **Europe/Vienna**, in filters, in request bodies and in responses (a few older fields return `d.m.Y`).

| Value | Means | In UTC |
| --- | --- | --- |
| `2026-07-01 14:00:00` | 14:00 summer time (CEST) | `2026-07-01T12:00:00Z` |
| `2026-12-01 14:00:00` | 14:00 winter time (CET) | `2026-12-01T13:00:00Z` |

Convert to Vienna time before you send a value, and treat values you read as Vienna time. Around the clock change, prefer whole days: on the last Sunday in October the hour from 02:00 to 03:00 happens twice.

### Rate limits

| What | Limit |
| --- | --- |
| All calls of one user or contact | 1,500 per minute (some tenants have a lower budget) |
| Sending email (`emails/send`) | 100 per minute |
| Bulk reads (`per_page` of 500 or more, beyond page 20) | per tenant 10 pages per minute from 07:00 to 19:00, 30 at night, at most 2 in parallel |

Above a limit the API answers **`429 Too Many Requests`** with a **`Retry-After`** header in seconds. Wait that long, then continue; on repeated 429s, double the wait each time. For whole tables, page with `filter[id_after]` (see above) and read pages one after another, not in parallel.

### Custom fields

Tenant-specific fields are called `custom_fields_0.<field>` (for all records of a type) or `custom_fields_<n>.<field>` (for one subtype only, for example one appointment category). Load them with `include=custom_fields_0`, write them with `{"custom_fields_0.i_1": 123}`. `GET https://api.1tool.cloud/v1/custom-fields/<area>` returns the display names.

## For AI systems

Claude and ChatGPT can use 1Tool directly through our MCP connector. Every call has a fixed `operationId` (for example `contacts.list`, `invoices.get`) by which an agent can name it unambiguously.

- **[llms.txt](https://api.1tool.cloud/v1/llms.txt)** lists every resource with a link to its own small OpenAPI file. An AI system loads only the resources it needs instead of the whole specification.
- **[This guide as Markdown](https://api.1tool.cloud/v1/public/docs.md)** for pasting into a prompt or a knowledge base.
- Each resource page offers its own OpenAPI download; the full specification is linked at the top left.

## More documentation

- [Placeholders in templates](https://api.1tool.cloud/docs/placeholders)
- [Workflows](https://api.1tool.cloud/docs/workflows)
- [Real-time channels](https://api.1tool.cloud/docs/channels)
- [Diese Dokumentation auf Deutsch](https://api.1tool.cloud/v1/docs?lang=de)
