Skip to content

Advanced Reporting API

Advanced Reporting API

These Organization-scoped resources are the supported contract for integrations and future official CLI support. They require no private browser API. This page does not imply that the current CLI implements Advanced Reporting commands.

Standard Project and Sprint reporting remain Core features with their existing project:read scope. Advanced resources require current Premium coverage, an enabled Advanced Reporting App, current Organization membership and Project access, and reports.advanced.use.

Scopes and Project restrictions

Use report:read for definitions, runs, dashboards, and exact selections. Use report:write for report definition creation, replacement, and deletion; it implies report:read. Existing tokens do not gain either scope. Create a replacement PAT when additional scopes are needed.

A PAT never bypasses current permissions. An all-resource PAT or Organization grant uses the user’s current authorized Projects. A Project-only PAT is restricted further to its granted Projects in the addressed Organization, including every dashboard widget and exact selection. It may resolve the parent Organization solely for that context. Responses remove out-of-grant source identifiers, names, counts, and data. sourceAvailability is complete, partial, or unavailable; clients must not infer missing totals from a partial result.

Project-only PAT mutations must use dataset.projects.mode = "selected", with every UUID within the token’s grants. all_authorized is rejected with 400 VALIDATION_ERROR. Personal reports belong to their creator. Organization-shared mutations still require owner/administrator shared-management permission; token scopes alone do not grant it. Shared definitions cannot be demoted to personal.

Endpoints

All paths below are relative to https://hamstik.com/api/v1/organizations/{organizationSlug}.

Method Path Purpose
GET, POST /advanced-reports List accessible definitions; create a definition
GET, PATCH, DELETE /advanced-reports/{reportId} Read, replace, or delete a definition
POST /advanced-reports/{reportId}/runs Evaluate the current report revision
GET /advanced-report-runs/{runId}/cells/{cellId}/items Page the exact captured selection
GET /advanced-dashboards List accessible dashboards
GET /advanced-dashboards/{dashboardId} Read an authorized dashboard
POST /advanced-dashboards/{dashboardId}/runs Evaluate authorized widgets

Schedules are managed in the private application; Public API schedule mutations are not part of this release.

Lists and models

Lists accept visibility=all|personal|organization, limit (default 50, maximum 100), and an opaque cursor. They return {items, page: {limit, hasMore, nextCursor}}. Continue with the returned cursor and identical parameters and credential. Cursors are bound to the actor, credential, Organization, visibility, Project ceiling, and limit. Unknown or repeated query fields are rejected.

Terminal window
curl -H "Authorization: Bearer $HAMSTIK_TOKEN" \
"https://hamstik.com/api/v1/organizations/$ORG_SLUG/advanced-reports?visibility=all&limit=50"

Report models contain a stable UUID, revision, name, description, visibility, owner public ID, timestamps, permissions, source availability, and a normalized authorized definition. A definition has version: 1, organizationId, dataset, and visualization; personal visibility is the default. Datasets specify Projects, fixed or rolling dates, timezone, filters, measure, grouping, and buckets. Dashboard models include authorized widgets, presentation, default filters, permissions, revision, and availability. User references use public identities, never email addresses.

The generated OpenAPI document defines the complete strict request and response schemas. For Project-only PATs, stored SqueakQL text is omitted and replaced by squeakqlRedacted: true in the report dataset or analytics definition, because query literals can name inaccessible resources. The original validated query still governs execution; the marker does not mean there is no filter. The marker is output-only and is rejected as mutation input. Do not copy a projected or redacted definition back as a replacement. To edit it, supply an intentional complete replacement, including the desired query.

Definition mutations and concurrency

POST requires a complete AdvancedReportInputV1 JSON body and Idempotency-Key. Store the normalized input in report.json and use a fresh key per intended mutation:

Terminal window
curl -i -X POST \
-H "Authorization: Bearer $HAMSTIK_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $MUTATION_KEY" \
--data-binary @report.json \
"https://hamstik.com/api/v1/organizations/$ORG_SLUG/advanced-reports"

Creation returns 201 and ETag: "advanced-report-1". GET also returns the current ETag. PATCH replaces the complete normalized definition, with If-Match: "advanced-report-<revision>" and a new Idempotency-Key. DELETE requires the same headers and the strict empty body {}; success is 204.

Terminal window
curl -i -X PATCH \
-H "Authorization: Bearer $HAMSTIK_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $MUTATION_KEY" \
-H "If-Match: $REPORT_ETAG" \
--data-binary @report.json \
"https://hamstik.com/api/v1/organizations/$ORG_SLUG/advanced-reports/$REPORT_ID"

An exact stale tag returns 412 REVISION_CONFLICT; missing If-Match returns 428 PRECONDITION_REQUIRED, and malformed tags return 400. If-Match: * requests mutation of the current readable revision. Weak tags and tag lists are invalid. Idempotent retries use the same body and key, return the original semantic response and ETag, and include Idempotency-Replayed: true. A report referenced by a dashboard cannot be deleted until its references are removed. Bodies are limited to 64 KiB.

Execution and exact selections

Report run bodies are strictly { "expectedRevision": 1 }. Dashboard run bodies are { "expectedRevision": 1, "filters": {} }, with optional normalized dashboard filters. These POST operations use report:read and do not require idempotency keys: every request explicitly creates a new server-timed evaluation. Clients cannot supply a historical evaluation timestamp.

Terminal window
curl -X POST -H "Authorization: Bearer $HAMSTIK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expectedRevision":1}' \
"https://hamstik.com/api/v1/organizations/$ORG_SLUG/advanced-reports/$REPORT_ID/runs"

Results retain evaluated time, effective dates and timezone, metric/reducer/unit, known zero versus null, sample and distinct-item counts, comparisons, warnings, and historical availability. A report run includes its projected definition and dataset. Dashboard runs return viewer-authorized widget results, per-widget state, source revision, and filter-application status. Incompatible filters and resource limits remain explicit; partial or unavailable data is never represented as a complete total.

A nonempty cell can include runId and cellId exact-selection references. Use the selection endpoint with limit and cursor (50 default, 100 maximum). It returns authorized Work Item fields plus the captured contribution or historical fact explaining that cell. References belong to the original actor and Organization, are short-lived, and require current Project authorization, including the PAT ceiling. Expiry returns 410 ADVANCED_SELECTION_EXPIRED. Unknown or another actor’s selection is 404 NOT_FOUND. Do not silently run the report again to replace an expired selection.

Recorded history boundaries remain authoritative. Current filters are not historical filters; label identity and current presentation caveats remain in force. No endpoint fabricates pre-history or supplies blocked-duration analytics. See Advanced Reporting for metric interpretation.

Responses and errors

Every response carries X-Request-Id and Cache-Control: no-store. Authenticated responses use the shared rate-limit headers. Errors use {error: {code, message, details?}, requestId} and never expose internal database details.

Code Meaning
ADVANCED_REPORTING_UNAVAILABLE Current App, Premium, or Advanced capability access is unavailable
ADVANCED_REPORT_REVISION_CONFLICT Report execution expected a different revision (409)
ADVANCED_DASHBOARD_REVISION_CONFLICT Dashboard execution expected a different revision (409)
ADVANCED_REPORT_RESOURCE_LIMIT The bounded computation or resource limit was exceeded
ADVANCED_REPORT_TIMEOUT The computation exceeded its time bound
ADVANCED_REPORT_IN_USE A dashboard still references the report
ADVANCED_SELECTION_EXPIRED The original exact selection expired (410)
REVISION_CONFLICT A mutation’s exact ETag is stale (412)

Authentication, scope, validation, cursor, idempotency, and rate-limit errors follow API operations. Requests always recheck live permissions; an older successful response is not an authorization grant.