Skip to main content

Template Parameters

The GET /file/design/parameter/{designId} endpoint retrieves the parameter structure for a specified template ID. You can check the schema for parameters needed for PDF or thumbnail generation.

Endpoint Information​

  • URL: https://api.re-port-flow.com/v1/file/design/parameter/{designId}
  • Method: GET
  • Authentication: appkey header required

Usage Examples​

cURL​

# Get latest version parameters
curl -X GET https://api.re-port-flow.com/v1/file/design/parameter/0eUDdgAjNXrrItA2 \
-H "appkey: your-application-key"

# Get specific version parameters
curl -X GET "https://api.re-port-flow.com/v1/file/design/parameter/0eUDdgAjNXrrItA2?version=1" \
-H "appkey: your-application-key"

JavaScript​

async function getDesignParameters(designId, version = null) {
const baseUrl = 'https://api.re-port-flow.com/v1';
const url = version
? `${baseUrl}/file/design/parameter/${designId}?version=${version}`
: `${baseUrl}/file/design/parameter/${designId}`;

const response = await axios.get(url, {
headers: {
'appkey': process.env.APP_KEY
}
});

return response.data;
}

// Usage example
const schema = await getDesignParameters('0eUDdgAjNXrrItA2');
console.log('Parameter schema:', schema);

Python​

def get_design_parameters(design_id, version=None):
base_url = "https://api.re-port-flow.com/v1"
url = f"{base_url}/file/design/parameter/{design_id}"

if version:
url += f"?version={version}"

headers = {
'appkey': os.getenv('APP_KEY')
}

response = requests.get(url, headers=headers)
response.raise_for_status()

return response.json()

# Usage example
schema = get_design_parameters('0eUDdgAjNXrrItA2')
print('Parameter schema:', schema)

Parameters​

ParameterTypeRequiredDescription
designIdstring✓Template ID (16-character alphanumeric, e.g. 0eUDdgAjNXrrItA2; path parameter)
versioninteger-Version number (query parameter, defaults to latest)

Response​

Success (200 OK)​

[
{ "name": "customerName", "type": "text", "label": "Customer name" },
{ "name": "invoiceNumber", "type": "text", "label": "Invoice number" },
{ "name": "amount", "type": "number", "label": "Amount" },
{
"name": "items",
"type": "array",
"label": "Items",
"spec": [
{ "name": "name", "type": "text", "label": "Item" },
{ "name": "price", "type": "number", "label": "Price" },
{ "name": "quantity", "type": "number", "label": "Quantity" }
]
},
{ "name": "issueDate", "type": "date", "label": "Issue date" }
]

The response is an array of parameter definitions that can be used to build an input form. name is the key to send in PDF generation params, and label is the display name. description is included only when configured. array and collection fields contain child definitions in spec.

Use name exactly as returned

name is chosen by the template author and may contain non-ASCII characters such as Japanese (for example "顧客名"). Always use it as-is as the params key — do not transliterate it or use label instead. If you design a template to be driven from the API, we recommend ASCII keys (for example customerName) and putting the human-readable name in label.

How keys are handled:

  • A key is exactly what the template author set. Re:port Flow never re-assigns keys or transliterates Japanese names into ASCII.
  • Matching is an exact match against name. There is no alias mechanism.
  • A key missing from params renders as empty (booleans keep their default). Extra keys that the template does not define are ignored (not an error).

type values:

TypeDescriptionExample
textString (the template's string and url types)"John Doe"
numberNumber1000
dateDate (ISO 8601)"2024-02-12"
booleanBooleantrue
collectionNested object defined by spec{ "name": "value" }
arrayArray whose row structure is defined by spec[{ "item": 1 }]

Errors​

404 Not Found​

{
"statusCode": 404,
"code": "DESIGN_NOT_FOUND",
"message": "The specified design does not exist.",
"error": "Not Found",
"details": [],
"docsUrl": "https://doc.re-port-flow.com/en/docs/guides/error-codes#design_not_found"
}

Cause: The code depends on whether you pass the version query.

versionTemplate ID does not existVersion does not exist
OmittedDESIGN_NOT_FOUND (The specified design does not exist.)(n/a — the latest version is used)
GivenDESIGN_VERSION_NOT_FOUND (The specified design and version do not exist.)DESIGN_VERSION_NOT_FOUND

A template ID of another workspace is treated the same as one that does not exist. The template ID is not format-checked, so a wrong ID always comes back as a 404, never as a 400. See Error Codes.

Use Cases​

Dynamic Form Generation​

Generate input forms dynamically from template parameters.

function createFieldElement(field, path = field.name) {
if (['text', 'number', 'date', 'boolean'].includes(field.type)) {
const input = document.createElement('input');
input.type = field.type === 'boolean' ? 'checkbox' : field.type;
input.name = path;
input.setAttribute('aria-label', field.label);

if (field.type === 'text' || field.type === 'number') {
input.placeholder = field.label;
}

return input;
}

if (field.type === 'array' || field.type === 'collection') {
const fieldset = document.createElement('fieldset');
const legend = document.createElement('legend');
legend.textContent = field.label;
fieldset.append(legend);

// Create the first array row. Add more rows with the same approach as needed.
const childPath = field.type === 'array' ? `${path}[0]` : path;
for (const child of field.spec ?? []) {
fieldset.append(
createFieldElement(child, `${childPath}.${child.name}`),
);
}

return fieldset;
}

return document.createDocumentFragment();
}

// Browser side. Fetch through your server
async function createDynamicForm(designId) {
const res = await fetch(`/api/design-parameters/${encodeURIComponent(designId)}`);
if (!res.ok) throw new Error(`Failed to get parameters: ${res.status}`);
const schema = await res.json();

// Build fields with DOM APIs instead of interpolating API values into HTML
const form = document.createElement('form');

for (const field of schema) {
form.append(createFieldElement(field));
}

return form;
}

// Your server (the appkey lives only here). Require login and limit designIds with an allow-list
const FORM_DESIGN_IDS = new Set(['0eUDdgAjNXrrItA2']);

app.get('/api/design-parameters/:designId', requireLogin, async (req, res) => {
if (!FORM_DESIGN_IDS.has(req.params.designId)) return res.status(404).end();
res.json(await getDesignParameters(req.params.designId)); // getDesignParameters from above
});

Because name and label are assigned as DOM properties, the browser does not interpret them as HTML markup.

Validation​

function validateObject(params, schema, path, errors) {
for (const field of schema) {
if (!Object.prototype.hasOwnProperty.call(params, field.name)) {
// This endpoint does not return required metadata, so omitted fields are skipped.
continue;
}

const value = params[field.name];
const fieldPath = path ? `${path}.${field.name}` : field.name;

if (field.type === 'text' && typeof value !== 'string') {
errors.push(`${fieldPath} must be a string`);
} else if (field.type === 'number' && typeof value !== 'number') {
errors.push(`${fieldPath} must be a number`);
} else if (field.type === 'boolean' && typeof value !== 'boolean') {
errors.push(`${fieldPath} must be a boolean`);
} else if (field.type === 'date') {
if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(value)) {
errors.push(`${fieldPath} must be in ISO 8601 date format`);
}
} else if (field.type === 'collection') {
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
errors.push(`${fieldPath} must be an object`);
} else {
validateObject(value, field.spec ?? [], fieldPath, errors);
}
} else if (field.type === 'array') {
if (!Array.isArray(value)) {
errors.push(`${fieldPath} must be an array`);
} else {
value.forEach((item, index) => {
const itemPath = `${fieldPath}[${index}]`;
if (item === null || typeof item !== 'object' || Array.isArray(item)) {
errors.push(`${itemPath} must be an object`);
} else {
validateObject(item, field.spec ?? [], itemPath, errors);
}
});
}
}
}
}

function validateParams(params, schema) {
const errors = [];

if (params === null || typeof params !== 'object' || Array.isArray(params)) {
return ['params must be an object'];
}

validateObject(params, schema, '', errors);
return errors;
}

// Usage example
const schema = await getDesignParameters('0eUDdgAjNXrrItA2');
const params = {
customerName: 'John Doe',
invoiceNumber: 'INV-001',
amount: 10000
};

const errors = validateParams(params, schema);
if (errors.length > 0) {
console.error('Validation errors:', errors);
}

Best Practices​

1. Cache Parameter Schema​

Parameter schemas don't change unless the template version changes. Cache and reuse them.

const schemaCache = new Map();

async function getDesignParametersCached(designId, version) {
const cacheKey = `${designId}:${version}`;

if (schemaCache.has(cacheKey)) {
return schemaCache.get(cacheKey);
}

const schema = await getDesignParameters(designId, version);
schemaCache.set(cacheKey, schema);

return schema;
}

2. Validate Before PDF Generation​

Get parameter schema in advance and validate to detect errors early.

async function generatePDFSafely(params) {
// 1. Get parameter schema
const schema = await getDesignParameters(params.designId, params.version);

// 2. Validate
const errors = validateParams(params.data, schema);
if (errors.length > 0) {
throw new Error(`Parameter errors: ${errors.join(', ')}`);
}

// 3. Generate PDF
return await generatePDF(params);
}

FAQ​

When does a template's parameter schema change?​

The schema does not change unless the template's version changes. For the same designId and version pair you can cache the schema you fetched and reuse it.

How do I fetch the parameters for a specific version?​

Pass version as a query parameter. If you omit it, the parameters for the latest version are returned.

Next Steps​