Lists the organization's report instances (each one a report for a period, generated from a template, draft or finalized), newest first, paginated by cursor. A workspace keeps the instances of all its accounts: filter one account with target_org_id, and draft/finalized with status. Items are summaries (template, period, account, PDF and portal state, page and block counts); fetch the pages with reports.instances.get. Each period comes with start_date and end_date when it is fixed (null for a named period, resolved when it renders). Members and viewers only see the accounts assigned to them; that filter and status read further until the page is full (up to 600 instances per call): keep following next_cursor while has_more is true. Requires view access to Reports.
Scope
reports:read
Permission
View the module
MCP tool
reports_instances_listOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.list".
Declared cost: up to 202 reads and 0 writes per call (they count against the daily quota).
Parameters
limitintegerqueryoptional
How many report instances per page (default 50, at most 200).
Default: 50
cursorstringqueryoptional
The next_cursor of the previous page, to get the next one; omit it for the first page.
target_org_idstringqueryoptional
Only the instances of this account (platform.orgs.list).
Returns one report instance with all its pages (sections) and blocks (including the AI text generated for it), its period, data source mapping, account, PDF state (has_pdf, pdf_job_status queued|running|failed) and portal state. Download the PDF with reports.instances.pdf_url. Not found if it does not exist in the organization; forbidden if it belongs to an account not assigned to you. Requires view access to Reports.
Scope
reports:read
Permission
View the module
MCP tool
reports_instances_getOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.get".
Declared cost: up to 1 reads and 0 writes per call (they count against the daily quota).
Parameters
instance_idstringpathrequired
The report instance id (reports.instances.list).
Response
idstring
titlestring
statusenum
Values: draft, finalized
has_pdfboolean
Whether it has a PDF (reports.instances.pdf_url gives the link).
descriptionstring | null
target_org_idstring | null
target_org_namestring | null
template_refobject | null
The template it was generated from.
date_rangeobject | null
The report's period.
last_pdf_generated_atnumber | null
When its PDF was made (epoch ms); null without a PDF.
pdf_job_statusenum | null
Values: queued, running, failed
pdf_job_errorstring | null
published_to_portalboolean | null
published_to_portal_atnumber | null
finalized_atnumber | null
finalized_bystring | null
created_from_deliveryboolean | null
ai_block_countnumber | null
ai_blocks_generatednumber | null
label_idsarray<string> | null
created_atnumber | null
updated_atnumber | null
created_bystring | null
created_by_namestring | null
Name of who created it («MB Suite» for the scheduler).
subtitlestring | null
Subtitle.
sectionsarray<object> | null
Pages and blocks (with the generated content of an instance).
cover_pageobject | null
Cover page settings; null without a cover.
table_of_contentsboolean | null
Whether it has a table of contents.
module_pagesarray<object> | null
Module pages (tasks, pacing, social, SEO) and where they go.
Generates a draft report instance for a period from a template: the organization's own (template_source=ORGANIZATION), a published one of the parent workspace (INHERITED) or a published system template (SYSTEM). Send the period (date_range: preset, config, label), optionally the account it is for (target_org_id, a child of the workspace) and the data_source_mapping (slot or platform of the template → data source id of that account, from reports.data_sources.list with the same target_org_id). With target_org_id the instance is kept in the workspace and its data sources are checked against that account's connections (own or inherited from the workspace), never the workspace's alone: an id the account does not have is 400 data_source_not_linked. The media plan of the period is linked automatically. AI text blocks are generated only from the MB Suite screen, with the AI credits of the person who generates the report: when the credit pool does not cover them, the instance is generated anyway and those blocks are left empty with ai_error_code (ai_credits_exhausted, ai_personal_limit or payment_required). Through the API, the MCP or MIA they are created empty, ready to generate from the editor. The period (date_range) is a preset ({preset: last_month}), fixed days ({start_date, end_date}) or the stored form (preset, config, label); the server fills in what is missing. Then export it with reports.instances.export_pdf. Fires reports.instance.generated. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_generateOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.generate".
Creates an empty draft report instance (one page, no blocks) for a period, to build by hand with reports.instances.update: title (default «Reporte sin título» in the caller's language), period (date_range: a preset, start_date and end_date, or the stored form), optionally the account it is for (target_org_id), its data source mapping and the platforms it may use. To start from a template use reports.instances.generate. Returns the instance id. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_createOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.create".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
date_rangeobjectbodyrequired
The report's period: a preset, or start_date and end_date, or the stored form (preset, config, label).
titlestringbodyoptional
Title; default «Reporte sin título» (in the caller's language).
target_org_idstringbodyoptional
The account the report is for; without it, this organization.
target_org_namestringbodyoptional
Optional: the account's name (the server fills it in).
data_source_mappingobjectbodyoptional
Template slot or platform → connection id of the account (google_ads:1234567890, from reports.data_sources.list).
Updates fields of a draft report instance: title, description, subtitle, pages (send the full sections array), period (date_range), cover page, table of contents, module pages and their own periods (module_date_ranges), theme, accent color, labels, allowed platforms, data source mapping and linked media plan (selected_media_plan_id). null removes the optional ones (cover page, theme, accent color, media plan, module periods). Finalized instances are read-only (409 report_instance_finalized): duplicate them to edit a copy. New platform data sources must be connected to the account whose data the report reads; new block types, metrics, dimensions and presets are checked (report_block_type_unknown, unknown_metric, unknown_dimension, preset_unknown), labels must exist (label_unknown, reports.labels.list) and the media plan too (media_plan_not_found). Fields go inside updates. Returns the updated instance. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_updateOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.update".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
instance_idstringpathrequired
The report instance id (reports.instances.list).
updatesobjectbodyrequired
The fields to change (null removes the optional ones).
Locks a draft report instance (status finalized, read-only) without generating its PDF; exporting the PDF also finalizes it. Finalizing one that is already finalized changes nothing (changed: false). Fires reports.instance.finalized. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_finalizeOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.finalize".
curl-X POST "https://api.mb-suite.com/v1/reports/instances/{instance_id}/finalize" \
-H"Authorization: Bearer $MB_API_KEY"
Try it with your test API key
With a test API key the request always goes to your practice organization: example data you can reset.
curl-X POST "https://api.mb-suite.com/v1/reports/instances/{instance_id}/finalize" \
-H"Authorization: Bearer $MB_TEST_KEY"
POST/v1/reports/instances/{instance_id}/duplicate
Duplicate a report instance
reports.instances.duplicate
WriteSince 2026-11-01
Copies a report instance into a new draft titled '<title> (Copia)' (the suffix in the caller's language: (Copia), (Copy) or (Cópia)) with new page and block ids, keeping its period and template. To reuse it for another account of the workspace, send target_org_id with that account's data_source_mapping (its media plan is re-matched). Works on finalized instances too (it is how they are edited). Returns the new instance id. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_duplicateOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.duplicate".
Declared cost: up to 104 reads and 1 writes per call (they count against the daily quota).
Parameters
instance_idstringpathrequired
The report instance id (reports.instances.list).
target_org_idstringbodyoptional
Copy it for another account of the workspace (with its own data_source_mapping); default the same one.
target_org_namestringbodyoptional
Optional: that account's name (the server fills it in).
data_source_mappingobjectbodyoptional
For another account: template slot or platform → its connection id.
curl-X POST "https://api.mb-suite.com/v1/reports/instances/{instance_id}/duplicate" \
-H"Authorization: Bearer $MB_API_KEY"
Try it with your test API key
With a test API key the request always goes to your practice organization: example data you can reset.
curl-X POST "https://api.mb-suite.com/v1/reports/instances/{instance_id}/duplicate" \
-H"Authorization: Bearer $MB_TEST_KEY"
DELETE/v1/reports/instances/{instance_id}
Delete a report instance
reports.instances.delete
IrreversibleSince 2026-11-01
Deletes a report instance; it stays 30 days in the trash (platform.trash.restore brings it back with its PDF, which is kept in storage). If it was published to the client portal it disappears from there too. Owners and admins delete any instance; anyone else with edit access to Reports only the ones they created (created_by), so whoever generates a report to export its PDF can remove it afterwards; any other is 403 role_required, also on the dry run. Outside the screen it needs a dry run and a confirm_token, or a key with deletion enabled.
With an API key, this DELETE runs directly: the record stays 30 days in the trash and the response carries its trash_item_id. With an OAuth token, and through the MCP, it needs dry_run → confirm_token.
Scope
reports:writeand “Allow deletions” (reports:delete in OAuth)
Permission
Edit in the module
MCP tool
reports_instances_deleteOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.delete".
Declared cost: up to 1 reads and 2 writes per call (they count against the daily quota).
Parameters
instance_idstringpathrequired
The report instance id (reports.instances.list).
Response
oktrue
trash_item_idstring
The trash item this deletion left: the item_id of platform.trash.restore (POST /trash/{item_id}/restore). Missing if nothing went to the trash.
trash_item_idsarray<string>
Only when the deletion left more than one copy: all of them, the first being trash_item_id.
trash_expires_atnumber
When the copy leaves the trash for good (epoch ms): 30 days after the deletion.
Deletes up to 500 report instances; each goes to the 30-day trash. Ids that do not exist or belong to an account not assigned to you are skipped; count says how many were deleted. Owners and admins only. Outside the screen it always needs a dry run (which lists what will be deleted) and its confirm_token.
Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.
Scope
reports:writeand “Allow deletions” (reports:delete in OAuth)
Permission
Edit in the module · Only owner, admin
MCP tool
reports_instances_bulk_deleteOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.bulk.delete".
Declared cost: up to 500 reads and 1000 writes per call (they count against the daily quota).
Parameters
instance_idsarray<string>bodyrequired
Report instance ids (reports.instances.list), up to 500.
Response
countnumber
trash_item_idsarray<string>
The trash items this deletion left, one per record: the item_id of platform.trash.restore (POST /trash/{item_id}/restore).
trash_expires_atnumber
When the copy leaves the trash for good (epoch ms): 30 days after the deletion.
Starts the PDF of a report instance in the background (status queued): the render reads every platform of its blocks live and takes up to two minutes; when it ends, reports.pdf.ready (or reports.pdf.failed) fires and the instance is finalized. If the PDF already exists it returns status ready with a signed download link valid for one hour. A job already running returns queued again. Generating the PDF of a draft finalizes it, so it needs edit access; a finalized one only needs view access. Daily PDF quota: each new render counts 1 against the pdf external quota of the organization that pays the call (by default 50 a day on a trial, 300 starter, 1,000 growth, 2,500 scale, 5,000 enterprise; it resets at 00:00 UTC); the MB-Quota-External-Platform (pdf), MB-Quota-External-Limit and MB-Quota-External-Remaining headers say what is left. Returning a PDF that already exists or a job already running does not use it up, but once the quota is used up this call fails with 429 quota_exceeded (details.quota.type external) until the reset, except for a job already running. To wait for a PDF poll reports.instances.get (pdf_job_status, has_pdf) or the reports.pdf.ready webhook, and download it with reports.instances.pdf_url: neither counts against the PDF quota. In the practice organization (test keys) nothing is rendered and no platform is read: the job finishes at once with a one-page stand-in PDF that says so (the instance is finalized and has_pdf is true, so the first poll of reports.instances.get finds it and reports.instances.pdf_url downloads it); the response carries simulated: true, and the call uses none of the PDF quota and fires no notification or webhook. With Google Ads, Google Business Profile, LinkedIn, TikTok or YouTube, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted (the permissions guide lists what each platform allows).
Scope
reports:write
Permission
View the module
MCP tool
reports_instances_export_pdfOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.export_pdf".
Declared cost: up to 1 reads and 2 writes per call (they count against the daily quota). Touches an external platform (pdf): it counts against the external operations quota.
curl-X POST "https://api.mb-suite.com/v1/reports/instances/{instance_id}/pdf" \
-H"Authorization: Bearer $MB_API_KEY"
Try it with your test API key
With a test API key the request always goes to your practice organization: example data you can reset.In the practice organization this operation is simulated: nothing is sent and the response carries simulated: true.
curl-X POST "https://api.mb-suite.com/v1/reports/instances/{instance_id}/pdf" \
-H"Authorization: Bearer $MB_TEST_KEY"
GET/v1/reports/instances/{instance_id}/pdf
Get a download link for the PDF of a report instance
reports.instances.pdf_url
ReadIdempotentSince 2026-11-01
Returns a signed link to download the PDF of a report instance, valid for one hour (expires_at), with its file name and when it was generated. Ask for a new link each time: links are never stored. 404 report_pdf_not_found if the PDF was never generated (start it with reports.instances.export_pdf) and report_pdf_missing if the file is no longer in storage. Requires view access to Reports. With Google Ads, Google Business Profile, LinkedIn, TikTok or YouTube, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted (the permissions guide lists what each platform allows).
Scope
reports:read
Permission
View the module
MCP tool
reports_instances_pdf_urlOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.pdf_url".
Declared cost: up to 1 reads and 0 writes per call (they count against the daily quota).
Publishes a finalized report instance of an account to that account's Client Portal (published: true), or removes it from there (published: false). Only finalized instances generated for an account can be published (409 otherwise). Setting the state it already has changes nothing (changed: false). Publishing fires reports.instance.published. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_publish_to_portalOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.publish_to_portal".
Creates a published template of the organization from the structure of a report instance: same pages and blocks with new ids, without the generated content, and each data source turned into a slot (ds_1, ds_2…) so the template can be used for any account. Returns the template id and fires reports.template.published. Requires edit access to Reports.
Scope
reports:write
Permission
Edit in the module
MCP tool
reports_instances_save_as_templateOn the full surface; on the compact one, mb_execute_operation with id: "reports.instances.save_as_template".