Skip to content
Hoursmith Docs
Webhooks

Event types & payloads

The 8 Hoursmith webhook event types and the signed JSON envelope they arrive in, including the data snapshot and payment object.

Every webhook delivery is a JSON envelope describing a single event. This page lists the event types Hoursmith emits and documents the envelope and its data payload.

Event types

Hoursmith emits exactly 8 event types. There are no wildcard subscriptions in v1 — subscribe to each type you want.

Event typeDescription
invoice.sentAn invoice was sent to a client.
invoice.paidAn invoice was marked paid.
invoice.payment_failedA payment attempt on an invoice failed.
time_entry.createdA time entry was created.
task.completedA task was marked complete.
task.createdA task was created.
client.createdA client was created.
project.createdA project was created.

The envelope

Every delivery has the same top-level shape:

{
  "id": "4f9c2a1e-....",
  "type": "invoice.paid",
  "created": 1717603200,
  "orgId": "00000000-0000-0000-0000-000000000000",
  "livemode": true,
  "data": {
    "invoice": { "/* full GET /api/v1/invoices/{id} shape */": true },
    "payment": { "/* ... */": true }
  }
}
FieldTypeDescription
idstring (UUID)Unique id for this event. All retries of one event share this id — use it to dedupe.
typestringThe event type, e.g. invoice.paid.
creatednumberWhen the event was created, as a Unix timestamp in seconds.
orgIdstring (UUID)Your workspace id.
livemodebooleantrue only in production. Test events are false.
dataobjectResource snapshot(s) for the event — see below.

The created field is the event creation time. It is not the signature timestamp — that lives in the t= value of the Hoursmith-Signature header. See Verify signatures.

The data object

data contains a snapshot of the resource the event is about. Each resource has the same shape as its API GET response — for example, the invoice object matches GET /api/v1/invoices/{id}. Keys are named after the resource:

Event typedata keys
invoice.sentinvoice
invoice.paidinvoice, payment
invoice.payment_failedinvoice, payment
time_entry.createdtime_entry
task.completedtask
task.createdtask
client.createdclient
project.createdproject

For the full field-by-field shape of each resource, see the API reference and the relevant resource docs: Invoices, Payments, Tasks, Clients, and Projects.

Payment events

invoice.paid and invoice.payment_failed include an additional payment object in data alongside the invoice:

{
  "id": "4f9c2a1e-....",
  "type": "invoice.paid",
  "created": 1717603200,
  "orgId": "00000000-0000-0000-0000-000000000000",
  "livemode": true,
  "data": {
    "invoice": { "/* full GET /api/v1/invoices/{id} shape */": true },
    "payment": { "/* the payment that succeeded or failed */": true }
  }
}

Switch on the envelope's type to route events, then read the matching key out of data. Because the id is stable across retries, record it before processing so repeated deliveries are no-ops.

Test vs. live

The livemode flag tells you whether an event is real:

  • Live events carry livemode: true.
  • Test events (sent from the UI to a new endpoint) carry livemode: false and include data.test: true. See Replay & test events.
Was this page helpful?

On this page