Z Zise Developers 简体中文

Download an export (the response body is xlsx, not JSON)

GET /v1/reports/{id}/content scope: merchant:read
Merchant account

⚠ The only endpoint in this layer with a non-JSON response. The response has Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, Content-Disposition: attachment, and Cache-Control: private, no-store. Authentication is required, and expired files must genuinely become unavailable, so no intermediate cache is permitted. An SDK that unconditionally calls JSON.parse on responses will fail here.

Every download rechecks the Key's authorization; this is not a link to forward elsewhere.

The file is typed xlsx: amount columns are Excel Numbers with decimal places and support SUM directly; UIDs / order numbers are text, preserving leading zeros and avoiding scientific notation. Opening CSV and manually changing column types cannot provide this, so CSV is no longer offered.

Path Parameters

FieldTypeRequiredDescription
id string Required Task ID; accepts rep_<uuid> or a bare <uuid>.

Response

200The xlsx file itself.
400state_invalid: the same response for three cases: not ready, generation failed, or expired and removed. ⚠ Query GET /v1/reports/{id} for status, error, and expires_at; this endpoint does not return internal state names. ⚠ Retrying the same ID does not change the result; create a new export instead.
403insufficient_scope: missing merchant:read.
404resource_not_found, including tasks belonging to another merchant, with the same response.

Additional Details

Columns by kind, in file order

daily:


day,line,asset,orders,
member_paid,member_paid_minor,
merchant_paid,merchant_paid_minor,
merchant_margin,merchant_margin_minor,
ledger_scale,display_scale

pnl and line:<line> add two window columns; the rest are the same:


period_from,period_to,line,asset,orders,
member_paid,member_paid_minor,
merchant_paid,merchant_paid_minor,
merchant_margin,merchant_margin_minor,
ledger_scale,display_scale

statements:


posted_at,business,ref_table,ref_id,asset,
merchant_paid,merchant_paid_minor,
ledger_scale,display_scale

⚠ The two window columns must be in the file, because every pnl row covers the entire window. Without the window in the file itself, exports for different periods would look identical while sitting together in your finance team's download folder.

Three conventions for your parser

  • Amounts are provided in two forms: *_paid / *_margin are Excel numbers ready for SUM; *_minor is the same amount as a fixed-point integer. ledger_scale is included on each row.
  • ⚠ Amount cells are blank when precision is unavailable, for delisted or unregistered assets. There is no fallback to 6 decimals. A blank is visible to a person; a number wrong by a factor of 100 is not. In this case ledger_scale / display_scale are also blank.
  • The window depends on kind: daily excludes today, because daily summaries are computed the next day and a row of 0 could be mistaken for no business today. It covers **the days days ending yesterday. pnl / line: / statements cover the last days days through now**, including today's partial data.

Two further details:

  • The line column may contain other, a fallback for a business table not yet registered in the mapping. This is not an error but should not persist; tell us if you see it.
  • Neither our revenue nor the costs we pay providers appear in the file. You see only what you paid. A format change does not remove this boundary.

merchant_margin = member_paid − merchant_paid, the member's actual payment minus the debit from your prepayment; it is not a standalone ledger column.

Request
curl -X GET 'https://api.zinfra.vip/v1/reports/{id}/content' \
  -H 'x-auth-token: Bearer $TOKEN'
const res = await fetch("https://api.zinfra.vip/v1/reports/{id}/content", {
  method: "GET",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
  },
});
// Keep monetary amounts as strings, never numbers.
const data = await res.json();
import requests

res = requests.get(
    "https://api.zinfra.vip/v1/reports/{id}/content",
    headers={
        "x-auth-token": "Bearer $TOKEN",
    },
)
# Use Decimal(str(...)) for amounts, not float.
data = res.json()
req, _ := http.NewRequest("GET", "https://api.zinfra.vip/v1/reports/{id}/content",
    nil)
req.Header.Set("x-auth-token", "Bearer $TOKEN")
res, err := http.DefaultClient.Do(req)
// Decode amount fields as string, not float64.
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.zinfra.vip/v1/reports/{id}/content"))
    .header("x-auth-token", "Bearer $TOKEN")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
// Use String / BigDecimal for amounts, not double.
$ch = curl_init('https://api.zinfra.vip/v1/reports/{id}/content');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'x-auth-token: Bearer $TOKEN',
  ],
]);
$res = curl_exec($ch);
// Use bcmath / strings for amounts, not floatval.
200
// No response example is declared in the specification for this operation.