⚠️ Deprecated. The self-service Developer API supersedes this page — see the export-hours recipe (GET /v1/sessions) and webhooks. The legacy sessions-export pull endpoint still works during the deprecation window (it now returns Deprecation / Sunset headers), but new integrations should use the /v1 API.

Exporting hours

BriefQR does not lock your data in. Hours leave the system through a provider-neutral export layer, so you can connect payroll, invoicing, or a time-tracking tool of your choice. There are two paths: a push path using a signed webhook, and a pull path using REST or CSV. Kimai is the reference connector that shows how it all fits together.

The export layer in short

  • Push: BriefQR sends each completed session to your endpoint as a signed webhook event.
  • Pull: You request sessions on your own schedule over REST, or download a CSV.
  • Neutral: The format is an open event schema, not tied to any single payroll vendor.

You can use one path or both. Most teams start with CSV to sanity-check the numbers, then move to the webhook for hands-off delivery.

The signed webhook

A webhook is a small message BriefQR sends to a URL you control whenever something happens, such as a session being completed or approved.

  1. In the dashboard, open Integrations and add a webhook endpoint.
  2. Enter the URL where you want events delivered.
  3. BriefQR shows a signing secret. Store it securely on your side.

Every delivery is signed with that secret. Your receiver should verify the signature before trusting the payload, which confirms the message really came from BriefQR and was not altered in transit. Reject any request whose signature does not match.

What the event payload represents

Each event describes one time-tracking fact, such as a completed work session. At a high level a payload carries:

  • An event type and a unique event identifier.
  • A reference to the operator, the client, and the location involved.
  • The clock-in and clock-out times and the resulting duration.
  • Any review signals attached to the session, such as a soft GPS flag.

Exact field names can change as the schema grows, so build your receiver to read fields by name and ignore fields it does not recognize. That keeps your integration working across updates.

REST and CSV pull

If you prefer to ask for data rather than receive it:

  • REST: Query sessions for a date range and pull them into your own system on a schedule that suits you.
  • CSV: Export a date range from Reports as a CSV file and import it into a spreadsheet or payroll tool. This is the simplest way to verify totals before automating.

The pull path returns the same session facts as the webhook, so you can mix approaches without reconciling two different models.

The Kimai reference connector

Kimai is an open-source time-tracking tool, and BriefQR ships a reference connector for it. Treat it as a worked example.

  • It shows how to receive BriefQR events and turn them into time entries in another system.
  • It is a template you can read, copy, and adapt for your own payroll or invoicing tool.
  • You do not have to use Kimai. The same patterns apply to any destination that accepts a webhook or an API import.

Adding an integration

  1. Decide push or pull. Pick the webhook for automatic delivery, or REST and CSV to pull on demand.
  2. For the webhook, add your endpoint URL and save the signing secret.
  3. Verify the signature on incoming events, then map the payload fields into your target system. The Kimai connector is a good starting point.
  4. Send a test session through BriefQR and confirm it lands correctly downstream.

Replaying failed deliveries

If your endpoint is down or returns an error, the delivery is recorded as failed. You do not lose the event.

  1. Open Integrations and find the delivery log for your endpoint.
  2. Review failed deliveries and the response that was returned.
  3. Once your endpoint is healthy, replay the failed deliveries to resend them.

Because each event carries a unique identifier, make your receiver idempotent: if the same event arrives twice during a replay, process it only once.

Where to go next