abletime.comOpen App

API Webhooks

AbleTime enables the use of webhooks, where a POST a signed JSON event is sent to a URL you host.

Create, list, delete, signing secrets, and the x-abletime-token header token live in Settings → Integrations → Webhooks. See Documentation → Integrations → Webhooks for details.

Registration constraints

When you create a webhook in Settings, you bind an event type, an API key, and an HTTPS target URL. The bound key must hold the read grant for that event's family. An organization may hold up to 25 active webhooks for any one event family. Revoking the bound API key stops deliveries for webhooks bound to that key.

Event types

Subscribe either to a single fine-grained type or to a whole family by its umbrella name.

Family

Types

Grant required

timeentry

timeentry.created

timeentry.read

task

task.created, task.assigned, task.unassigned, task.state_changed, task.archived, task.blocked, task.unblocked, task.scheduled, task.updated

task.read

epic

epic.created, epic.activated, epic.archived

task.read

comment

comment.created, comment.updated

comment.read

milestone

milestone.created

milestone.read

invoice

invoice.generated, invoice.due, invoice.paid, invoice.overdue, invoice.uncollectible, invoice.voided

billing.read

Umbrella names timeentry, task, epic, milestone, invoice, and comment subscribe to every fine-grained type in that family and require the same grant as the family row.

What arrives

json
{
  "eventType": "task.state_changed",
  "eventId": "01J9Z3K7QF8XM2P0ABCDE",
  "occurredAt": "2026-08-02T09:30:00.000Z",
  "data": { }
}

The data field holds the affected record in the same shape its own GET endpoint returns, as it stands at the moment of delivery.

Headers

Every POST carries three Standard Webhooks headers, plus an optional AbleTime filter header.

Header

Contents

webhook-id

The event identifier, identical across retries of the same event

webhook-timestamp

Seconds since the epoch

webhook-signature

One or more space-separated v1,<base64> values, any one of which may match

x-abletime-token

The header token from Settings (when present). Useful for no-code filters; not a substitute for signature verification in code

Verifying a delivery

Use a Standard Webhooks library with your whsec_ secret from the Webhook Created dialog. The signed content is {webhook-id}.{webhook-timestamp}.{raw body}, HMAC-SHA256 with the base64-decoded remainder of the secret. Reject anything whose signature does not verify, or whose timestamp is far from the present.

Verify against the raw request body, exactly as received. Parsing and re-serialising the JSON first will change the bytes and the signature will not match.

Responding and retries

  • Answer with any 2xx status, and answer quickly. Do your real work after acknowledging.

  • Each attempt is given about ten seconds before it is treated as failed.

  • An event is attempted up to three times. A retry becomes due roughly ten minutes after the previous attempt.

  • Redirects are not followed. Register the final URL.

  • After the last attempt the delivery is abandoned. There is no delivery log or replay screen in the product; the current state of a record is always readable from the API.

Delivery is at-least-once. An event you have already acknowledged can arrive again, so process deliveries idempotently: record webhook-id per endpoint and discard one you have already handled. The same event sent to several destinations carries the same webhook-id to each.