Use when retrieving monitoring report data for dashboards or frontend report screens via `/v1/monitoring/report*`; do NOT use for creating new report generators or running `generate_report`.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Use when retrieving monitoring report data for dashboards or frontend report screens via `/v1/monitoring/report*`; do NOT use for creating new report generators or running `generate_report`.
requires
[]
Skill: Read Monitoring Reports API
When to Use
Use this skill when the task is to fetch monitoring report metadata, list rows, row detail, or summary metrics from the monitoring report endpoints.
Use it when frontend code needs filter/sort/pagination behavior for monitoring reports.
If the request is specifically about acquisition report interpretation (funnel tiers, top assets/workshops, attribution patterns), prefer bc-monitoring-read-report-acquisition.
Do NOT use this skill to build a new report type or modify report generation logic.
Do NOT use this skill for non-monitoring report domains such as admissions, commission, or marketing report endpoints.
Concepts
Monitoring report retrieval is registry-driven: the client calls one route pattern with report_type instead of one endpoint per report.
Access is academy-scoped and requires capability read_monitoring_report.
Multi-academy scope is supported by passing comma-separated academy ids in header/query, e.g. Academy: 1,2,3.
List retrieval defaults to the latest report date when date is not provided (for report types that define a date field).
Workflow
Resolve scope and auth before calling any endpoint.
Send Authorization: Token <token>.
Send Academy: <academy_id> or comma-separated ids (1,2,3) because these endpoints enforce academy capability scope.
Discover available report types.
Call GET /v1/monitoring/report.
Use returned filters and sort_fields for dynamic UI query builders.
Fetch report rows for a selected type.
Call GET /v1/monitoring/report/{report_type}.
Apply only allowed filters and sort values to avoid validation errors.
Fetch summary metrics when needed by widgets/cards.
Call GET /v1/monitoring/report/{report_type}/summary.
Keep list and summary filters consistent so numbers match the table scope.
Fetch one row detail for drill-down panels.
Call GET /v1/monitoring/report/{report_type}/{report_id}.
Use report_id returned from Step 3.
Trigger async generation only when explicitly requested.
Call POST /v1/monitoring/report/{report_type}/generate.
Use one date strategy per request (date, range, or days_back).
Requests are deduplicated by report/date scope unless force=true.
Poll generation job state and queue health.
Call GET /v1/monitoring/report/{report_type}/generate/{job_id} for one job.
Call GET /v1/monitoring/report/generate-jobs for pending/running/completed lists.
Handle validation failures predictably.
If filters/sort are rejected, rebuild query using only discovery metadata from Step 2.
If report type is unknown, refresh type list from Step 2 before retrying.
Optional body field:force (bool) to bypass dedup and create a new job.
Academy scope: generation uses read_aggregate resolution on the Academy header. If the header lists multiple academies and the user has the capability on all of them, the API creates one parent job (academy_id null) plus one child job per academy and returns only the parent (202 when new work is queued, 200 when the batch is already pending/running with the same parent fingerprint). Celery runs per child only; the parent row aggregates status/progress from children.
Partial capability: if the header requests academies the user cannot access, applied academies are the intersection; when that is more than one academy but not the full requested set, only child jobs are created (no parent). When exactly one academy applies, a single child job is returned as today.
Behavior: returns one job object or an array of child jobs (partial multi-academy case only).
Status values:PENDING, RUNNING, DONE, PARTIAL, ERROR, CANCELLED
Delete behavior:DELETE /v1/monitoring/report/{report_type}/generate/{job_id} is allowed only for terminal jobs (DONE, PARTIAL, ERROR, CANCELLED). Active jobs (PENDING, RUNNING) return validation error. Deleting a parent job is blocked while any child is still PENDING or RUNNING; otherwise delete cascades to children.
Primary use case: list pending/running generation jobs in dashboards.
Parent visibility: if a parent batch has children for academies A and B, a caller whose scope is only A sees only the child row for A (not the parent). If the caller’s scope includes every child academy in that batch, the list returns only the parent row for that batch (children are omitted so the batch is not duplicated). Standalone jobs (parent_id null, academy_id set) behave as before.
included_academies: on parent-only batch rows (academy_id null, parent_id null), each item includes included_academies: an array of { id, slug, name } for every academy covered by child jobs in that batch (sorted by id). For child rows or single-academy jobs, included_academies is null.
Missing academy scope header: API returns 403 with missing academy message. Send Academy header and retry.
Missing capability: API returns 403 capability error. Use a user/role with read_monitoring_report.
Unknown report type: API returns 404 with report-type-not-found. Re-run discovery endpoint and use a supported slug.
Unsupported filters: API returns 400 with unsupported-filter. Remove unknown query params and retry with allowed keys only.
Invalid sort value: API returns 400 with invalid-sort-field. Use one of sort_fields from discovery response.
Academy filter mismatch: API returns 400 with academy-filter-mismatch if query academy differs from scoped academy. Keep them aligned.
Event vs identity counts (acquisition): use by_funnel_tier for event-level analysis and by_funnel_tier_identities for deduped person-level funnel views. Same person can appear as both EVENT_RSVP and EVENT_ATTENDED on different (or same) days; identity dedupe still picks one best tier per identity.
Invalid date strategy on generation: API returns 400 with date-combination/range slugs. Send only one strategy and valid ranges.
Parent job detail with partial scope:GET .../generate/{job_id} for a parent id returns 404 if the caller’s academy scope does not include every child academy in that batch (use child job ids instead).
Checklist
Called GET /v1/monitoring/report and selected a valid report_type.
Sent Authorization and Academy headers on every request.
Used only allowed filters and sort fields from discovery metadata.
Queried list and summary with the same filter scope when showing one dashboard view.
Used detail endpoint only after obtaining report_id from list results.
Handled 400/403/404 errors with explicit retry behavior.
For generation, used exactly one strategy (date, range, or days_back).
Used force=true only when intentionally creating a duplicate regeneration job.