Skip to navigation

Generate a report

View as Markdown

Computes a report over your call or contact data and returns it in data, synchronously. The shape of data depends on type, and data.type echoes it. Use GET /api/reports/types for the catalog. For raw rows instead of aggregates, use POST /api/exports.

  • date_from / date_to accept an ISO 8601 datetime (offsets allowed) or a bare YYYY-MM-DD date. Since 2026-09-15 a bare date is a day in your workspace’s timezone: date_from starts at 00:00 local and date_to ends at the last instant of that day local, so both ends of the range are genuinely inclusive (date_to: "2026-08-31" used to stop at midnight UTC and leave out August 31). A value that carries a time is used as the exact instant you sent. A workspace with no timezone, or an unrecognised one, falls back to the platform zone America/Bogota. The range may not exceed 366 days and is matched against the call’s (or contact’s) created_at.
  • Day buckets inside a report (cost_per_call’s time series, for example) are also your workspace’s days.
  • campaign_ids filters roi_analysis and campaign_comparison. contact_funnel uses only the first id, and cost_per_call and agent_performance ignore it.
  • period is optional and changes nothing: when omitted the report is identical. format accepts only json (the default); any other value, including pdf, is refused with 400 before the rest of the body is checked.

These reports count CONNECTIONS, not conversations. They do not apply the no_effective_contact rule used by /api/analytics/*: a report’s denominator is dials and connections, which answers a different and equally useful question — how much of your dialling reached a human at all. For a success rate over conversations, read successRate from GET /api/analytics/overview. The two are not meant to match.

Three fields were renamed on 2026-09-16, with no change to any figure. successfulCalls was status = 'completed' (the call connected) and successRate was connected over dialled (the share of dials that were answered); neither ever measured success. The arithmetic is unchanged — only the names now say what they count. The old keys are still sent, carrying the same values, and are kept for one release: they are removed once the dashboard, the Zapier app and the MCP tools are all on the new names. No sunset date has been set.

ReportNew fieldDeprecated alias
roi_analysisconnectedCallssuccessfulCalls
roi_analysiscostPerConnectedCallcostPerSuccessfulCall
campaign_comparison, agent_performanceconnectionRatesuccessRate

How each report counts:

  • roi_analysis: counts only completed calls with a duration, so connectedCalls always equals totalCalls. Cost is minutes × Jelliu’s internal cost per minute. The human cost is minutes × an hourly human-agent rate ÷ 60.
  • campaign_comparison / agent_performance: connectionRate is the percentage of calls in the range with status completed. Rows are ranked by it, highest first — the same ordering the deprecated successRate produced, since the two carry the same value. agent_performance credits each call to the agent of its campaign, so calls without a campaign are not counted.
  • cost_per_call: one point per day with completed calls, oldest first, bucketed in your workspace’s timezone (since 2026-09-15; it was the UTC day before). Days without calls are left out.
  • contact_funnel: contacts created in the range, grouped by status. The known stages (pending, called, converted, dnc) come first; any other status is appended after them.

Side effects. Read-only on your data. The request is written to the audit log as report.generate.

Idempotency. Safe to retry. Nothing is stored, and the same parameters return the same figures unless new data arrived.

Webhook events. Emits audit.log_recorded to webhooks subscribed to it. See Webhooks.

Access

  • Required scope: write (it is a POST). Human users need the owner, admin or member role; viewers and billing users are refused.
  • Rate limit: General API — 120 requests/min per workspace on Starter or with no active plan, 200 on Growth, 300 on Business, 600 on Enterprise. See Rate limits.
  • Plan: Requires an active subscription (active, trialing or past_due); without one the request is refused with 403 BILLING_ERROR (metadata.kind: subscription_required).

Authentication

AuthorizationBearer

Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.

ScopeGET / HEADPOST / PUT / PATCH / DELETEAdmin-only routes
readYesNoNo
writeYesYesNo
fullYesYesYes

Operations restricted to admins or owners reject keys without the full scope with 403, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See Authentication.

Request

Unknown keys are ignored.
typeenumRequired

Which report to compute; it decides the shape of data. roi_analysis: cost, savings vs. human agents and ROI. campaign_comparison: campaigns ranked by success rate. cost_per_call: daily cost time series. agent_performance: agents ranked by success rate. contact_funnel: contacts by status and conversion rate.

Allowed values:
date_fromstringRequired

Inclusive start. ISO 8601 datetime (offsets allowed), or YYYY-MM-DD meaning 00:00 on that day in your workspace’s timezone.

date_tostringRequired

Inclusive end. ISO 8601 datetime, or YYYY-MM-DD meaning the last instant of that day in your workspace’s timezone (since 2026-09-15 the day itself is included). At most 366 days after date_from.

periodenumOptional

Optional label for the range. When sent it must be one of the values below, but it does not change the computation; only date_from / date_to do. Omitting it and sending daily, weekly, monthly, quarterly or custom all produce the same report.

Allowed values:
campaign_idslist of stringsOptional

Restrict to these campaigns. Applied by roi_analysis and campaign_comparison. contact_funnel uses only the first id; the other types ignore it. Each item must be a UUID.

formatenumOptionalDefaults to json

Only json is supported, and it is the default. Any other value (for example pdf) is refused with 400; PDF output is not available.

Allowed values:

Response

The computed report. The shape of data depends on type.

dataobject

One of five report shapes, selected by type.

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
429
Too Many Requests Error