# API and webhooks

Two things connect docket to the tools around it. The **API** lets a script or an automation tool
read and write what a person can in the app. **Webhooks** tell an address of yours when something
happened, so nothing has to ask again and again.

## Switching the API on

An admin switches it on under **Admin → Integrations → API**. Until then nobody can make a key,
and no key works.

## API keys

Every person makes their own keys in their profile settings, under **API keys**. A key acts as the
person who made it, with exactly their role: a time tracker's key sees their own projects and time,
an admin's key sees the figures.

- Making a key asks for your password.
- The key is shown **once**, when you make it. docket keeps only a fingerprint of it. Lost keys
  are replaced, not recovered.
- A key expires after 90 days unless you pick 30 days, a year or **Never**.
- A key stops working when you remove it or when the admin switches the API off.
- A key is deleted when its owner changes their password, is archived, or when an admin signs
  everyone out. Automations using it stop until you make a new key; signing out of docket leaves
  keys alone.
- What only a signed-in person does stays closed to keys: the workspace's settings, users, the
  connections to Jira and AI apps, and keys and webhooks themselves.
- A key may send 120 requests a minute.

## Calling the API

docket's API is GraphQL, the same one the app uses. It lives at your workspace's address:

```
POST https://yourworkspace.docket.rocks/graphql
Authorization: Bearer dkt_…
Content-Type: application/json

{ "query": "{ viewer { id } }" }
```

The schema, with every query and mutation and a description on each, is at `/graphql/schema` (send
the same header). Ids in webhook events are the ids the API takes. The
[API guide for developers](https://docket.rocks/en/docs/api-guide) walks through the common calls.

The API is the app's own, so it grows with the app. A field that goes away is marked as
deprecated in the schema first.

## Webhooks

An admin adds a webhook under **Admin → Integrations → API**: an https address and the events it
should hear about. An n8n *Webhook* node, a Make *Custom webhook* or a Zapier *Catch Hook* gives you
such an address.

| Event | When |
|-------|------|
| `project.created` | a project is created |
| `ticket.created`, `ticket.closed`, `ticket.reopened` | a ticket is created, closed or reopened (not tickets mirrored from Jira when they are created) |
| `time_entry.created` | time is booked (not worklogs taken over from Jira) |
| `quotation.published`, `quotation.confirmed`, `quotation.canceled` | a quote goes out, is confirmed or cancelled |
| `order_confirmation.published`, `delivery_note.published` | the document goes out |
| `invoice.published`, `invoice.paid`, `invoice.payment_reversed`, `invoice.canceled` | an invoice goes out, is marked paid, the payment is taken back, or it is cancelled |

Each event is a small JSON document: what happened, when, in which workspace, who did it, and the
record's id and a few facts. An invoice carries its number, dates, net and gross.

```json
{
  "id": "6c1f…",
  "event": "invoice.paid",
  "created_at": "2026-11-12T09:30:00Z",
  "workspace": "yourworkspace",
  "actor": { "id": "…", "name": "Ada Lovelace" },
  "data": { "type": "invoice", "id": "…", "number": "20042", "status": "paid", "net": 4230.0, "gross": 5033.7, "currency": "EUR" }
}
```

### Checking that it is docket

Every delivery is signed with the webhook's secret, which the webhook's row shows:

```
X-Docket-Signature: t=1794475800,v1=5f3a…
```

`v1` is the HMAC-SHA256 of `<t>.<body>` with the secret. Compute it yourself and compare; refuse
deliveries whose `t` is old. `X-Docket-Delivery` stays the same when a delivery is repeated, so
you can drop repeats.

### When your address doesn't answer

Any answer in the 200s counts as arrived. Otherwise docket tries again, five times within about
an hour, then gives up on that delivery. After twenty deliveries in a row that didn't
arrive, docket switches the webhook off; an admin switches it on again. The webhook's row lists its
latest deliveries with the answer each got, for two weeks.

docket only delivers to https addresses on the public internet.

Related: [API guide for developers](https://docket.rocks/en/docs/api-guide) · [Connect AI apps](https://docket.rocks/en/docs/ai-connections) · [User roles](https://docket.rocks/en/docs/user-roles)