Coze integration (OpenAPI plugin)
You can call Re:port Flow from a Coze bot (ByteDance's AI agent platform) and generate business-document PDFs straight from a conversation. Coze exposes external services as plugins defined by OpenAPI, so you register the Re:port Flow REST API as one.
An official listing in the Coze Plugin Store is in preparation. For now, follow the steps below to register Re:port Flow as your own private plugin in your Coze account. It uses your own workspace API key, so nothing is shared with other users.
Coze or MCP — which should I use?
Re:port Flow offers two entry points for AI agents. Pick based on whether your client speaks MCP.
| Client | Recommended |
|---|---|
| Claude Desktop / Claude Code / Cursor / VS Code | MCP server (reportflow-mcp) |
| Coze bots and workflows | The plugin approach on this page |
The MCP server authorizes each user through OAuth 2.0, while a Coze plugin connects with OpenAPI plus an API key. Both call the same Re:port Flow API, so the generated PDF is identical.
What you need first
- A Re:port Flow workspace — create one at re-port-flow.com
- An application key (a string starting with
ak_) — found under Workspace settings → API連携. See API keys - At least one design (template) to generate from. If you have none yet, copy one from the template gallery
Registering the plugin in Coze
In the Coze dashboard choose Create plugin → Create a plugin based on API, then configure it as follows.
1. Basic settings
| Field | Value |
|---|---|
| Plugin URL (base URL) | https://api.re-port-flow.com/v1 |
| Authorization method | Service (sends a token in a header) |
| Location | Header |
| Parameter name (Key) | appkey |
| Service token | Your application key (ak_...) |
The header name appkey is lowercase. A wrong value returns 401; a missing header returns 412. See Authentication for how to tell them apart.
2. Add four tools
Use Coze's "Add tool" to register these four. This is also the order the agent should call them in.
| Tool | Method | Path | Purpose |
|---|---|---|---|
listTemplates | GET | /file/designs | List templates in the workspace (returns id and latestVersion) |
getDesignParameters | GET | /file/design/parameter/{designId} | Get the parameter schema the template expects |
generatePdfAsync | POST | /file/async/single | Start generation; returns requestId and files[] as JSON |
downloadGeneratedFile | GET | /file/download/{requestId}/{fileId} | Confirm the job finished (see below) |
Request and response structures are documented here:
The request body for generatePdfAsync looks like this:
{
"designId": "0eUDdgAjNXrrItA2",
"version": 1,
"content": {
"fileName": "invoice_2026-08.pdf",
"params": {
"customerName": "Sample Inc.",
"invoiceNumber": "INV-2026-0812",
"amount": 110000
}
}
}
The keys inside params must match the name of each field returned by getDesignParameters. They differ per template, so always fetch the schema instead of hard-coding them.
3. Write the tool descriptions
A Coze agent decides which tool to call by reading its description. Make sure both of these are in the text — they change behaviour in practice:
- Always call
getDesignParametersbeforegeneratePdfAsync, and never invent parameter values. Without this, the agent will happily fillparamswith fabricated data and produce a wrong document. - A
202fromgeneratePdfAsyncmeans "queued", not "done". Report completion only afterdownloadGeneratedFilereturns200. Without this, delayed or failed jobs get announced to the user as finished documents. - Do not set
shareType. Leave it at the default"01"(workspace only).
Why async instead of sync generation?
POST /file/sync/single returns the raw PDF bytes as the response body, and the identifiers you need afterwards (File-URL, Request-Id, X-File-Mapping) are sent only as response headers.
Coze builds a tool's output from the response body, so registering the sync endpoint leaves the agent with "the PDF was created, but I cannot extract anything to show the user". From a chat agent, use POST /file/async/single, which returns JSON.
Sync generation itself works exactly as described in Sync single PDF and is fine for clients that can read response headers, such as your own backend.
How do I know generation finished?
The 202 Accepted from generatePdfAsync means the job was queued, not that the PDF exists. Stopping there makes the agent answer "done" even when generation is delayed or has failed.
Re:port Flow has no dedicated job-status endpoint. You confirm completion through the download endpoint:
GET https://api.re-port-flow.com/v1/file/download/{requestId}/{fileId}
200— the file exists, generation is complete. Only now should you tell the user it is ready404— not available. "Still generating" and "wrong ids" are indistinguishable here. Wait a few seconds and retry a few times before concluding it failed
Take requestId and fileId from the generatePdfAsync response (requestId and files[0].fileId). The response body is the PDF itself, but for the completion check only the status code matters.
If you want a guaranteed-complete result in a single call, sync generation (/file/sync/single) provides it — but as described above, Coze cannot extract the identifiers from its response. Sync is the simpler choice when you route through your own backend.
How do I hand the PDF to the user?
Once completion is confirmed, hand over files[].share.url from the generatePdfAsync response. Whether opening that link requires a Re:port Flow login depends on the shareType you sent.
shareType | Meaning | Needed to open the link |
|---|---|---|
"01" (default) | Workspace only | A Re:port Flow login |
"02" | Invited users | An invitation plus login |
"03" | Public URL | Nothing — anyone with the URL can read it |
Do not reach for "03" merely because the user wants to open the file from chat. "03" means everyone who has the URL can read the document, which for an invoice exposes your customer's details.
Use "03" only when the user has explicitly asked to publish the document, and consider pairing it with passcodeEnabled: true.
Where do the templates come from?
listTemplates responds with an object — { "designs": [...], "total": 12, "page": 1, "pageSize": 30, "totalPages": 1 } — not a top-level array. If designs is an empty array, the workspace has no designs yet. Copy a public template — invoice, quotation, receipt and more — from the template gallery into your workspace, and it will appear in listTemplates from then on.
The gallery search API (GET https://re-port-flow.com/api/v1/public/templates) needs no authentication, so you can register a separate no-auth plugin just for browsing templates. Note that a gallery slug cannot be used to generate a PDF — generation needs the designId you get after copying.
FAQ
Does this work on Coze's free plan?
There is no restriction on the Re:port Flow side. Whether you can create plugins depends on Coze's own plan rules. Re:port Flow's FREE plan allows 30 generated files per month.
Can I pass Chinese text as parameter values?
Yes. Re:port Flow handles UTF-8 strings directly and supports Japanese typography including kinsoku processing and font embedding. The catch is that the font embedded in your template must contain the characters you use — pick a font that covers Simplified or Traditional Chinese in the design editor if you need them.
Are there rate limits?
Per workspace: 30 req/min for the sync endpoints and 100 req/min for async and download endpoints. Exceeding a limit returns 429 with a Retry-After header. See Limitations.
What should I check when generation fails?
Start with the HTTP status. A 400 almost always means params does not match the template schema — compare your key names and types against the getDesignParameters output. 401 and 412 are authentication problems. See Error handling.