rendry-io · Schema
SyncRenderResponse
CompanyImage RenderingPDF GenerationTemplate EngineAPIAI Integration
Properties
| Name | Type | Description |
|---|---|---|
| mime_type | string | Effective output MIME type on success, including request overrides. |
| credits_charged | number | Actual credits debited by this successful render attempt; zero when no charge was made. |
| job_id | string | |
| status | string | |
| result_url | string | Path under /api/v1/files/… relative to the API origin — prefix https://rendry.io to download. Historical image results are public. New document attempt files and their page previews require the authen |
| error | string | On a refusal (status error): the machine code — see Refusal. |
| message | string | On a refusal: the sentence that explains the code. |
| diagnostics | array | On variables_unresolved: why the template's variables do not resolve for this call. |
| text_fit | array | A LIST, one entry per measured layer, each naming its own layer in `id` — not a map keyed by layer id. Actual per-layer text metrics in DSL layout coordinates: requested size, fitted_size, text_w/text |
| warnings | array | Document profile (pdf/html): which fragments were rasterized and stopped being text. |
| pages_used | array | preset_id of every page actually rendered — the same call twice gives the same list. |
| chart_fit | array | What the engine decided about each chart layer: the chosen scale, how many values were drawn and how many labels fit. Computed from the preset and the data, so it also comes back without a render |
| page_previews | array | pdf only: raster pictures of the pages of the file this call just produced — page 1 unless preview_pages named others. Free of extra charge: the pages were drawn in order to make the document. Absent |
| geometry | object | |
| expires_at | string | Server-owned file deadline: authenticated live/test output expires 365 days after completion; guests expire 72 hours after batch creation. |
| ai_content | string | Present only when the rendered output contains an owned AI image; the artifact carries composite AI-content metadata. |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/rendry-io/json-schema/rendry-io-sync-render-response-schema.json",
"title": "SyncRenderResponse",
"x-generated": "2026-10-31",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/rendry-io-openapi.json#/components/schemas/SyncRenderResponse",
"type": "object",
"properties": {
"mime_type": {
"type": "string",
"description": "Effective output MIME type on success, including request overrides."
},
"credits_charged": {
"type": "number",
"description": "Actual credits debited by this successful render attempt; zero when no charge was made."
},
"job_id": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"success",
"error"
]
},
"result_url": {
"type": "string",
"description": "Path under /api/v1/files/… relative to the API origin — prefix https://rendry.io to download. Historical image results are public. New document attempt files and their page previews require the authenticated owner; a user asset (user_assets/…) is served only to its owner."
},
"error": {
"type": "string",
"description": "On a refusal (status error): the machine code — see Refusal."
},
"message": {
"type": "string",
"description": "On a refusal: the sentence that explains the code."
},
"diagnostics": {
"type": "array",
"items": {
"$ref": "#/$defs/VariableDiagnostic"
},
"description": "On variables_unresolved: why the template's variables do not resolve for this call."
},
"text_fit": {
"type": "array",
"items": {
"$ref": "#/$defs/TextFit"
},
"description": "A LIST, one entry per measured layer, each naming its own layer in `id` — not a map keyed by layer id. Actual per-layer text metrics in DSL layout coordinates: requested size, fitted_size, text_w/text_h and box_w/box_h. Finishing and preview display resizing do not change these values; use geometry to map frames onto the displayed image. The clones of one repeat template arrive COLLAPSED into a single entry that carries the template id, the row count, the worst row and the rows that shrank or overflowed — that entry has collapsed_clones: true and is the only shape that differs from TextFit."
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Document profile (pdf/html): which fragments were rasterized and stopped being text."
},
"pages_used": {
"type": "array",
"items": {
"type": "string"
},
"description": "preset_id of every page actually rendered — the same call twice gives the same list."
},
"chart_fit": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"chart_type": {
"type": "string"
},
"values": {
"type": "integer",
"description": "how many numbers the series had after dynamic_data was applied"
},
"labels": {
"type": "integer"
},
"y_min": {
"type": "number"
},
"y_max": {
"type": "number",
"description": "the scale the ENGINE picked — this is why a bar is that tall"
},
"y_step": {
"type": "number"
},
"bars": {
"type": "integer",
"description": "bars or sectors actually drawn; fewer than values means some were dropped"
},
"labels_drawn": {
"type": "integer",
"description": "labels that fit the declared gutters; zero with non-zero labels means no room was reserved"
},
"plot_w": {
"type": "number"
},
"plot_h": {
"type": "number"
}
}
},
"description": "What the engine decided about each chart layer: the chosen scale, how many values were drawn and how many labels fit. Computed from the preset and the data, so it also comes back without a render"
},
"page_previews": {
"type": "array",
"items": {
"$ref": "#/$defs/PagePreview"
},
"description": "pdf only: raster pictures of the pages of the file this call just produced — page 1 unless preview_pages named others. Free of extra charge: the pages were drawn in order to make the document. Absent for every other format, and for a pdf whose pictures could not be stored."
},
"geometry": {
"$ref": "#/$defs/RenderGeometry"
},
"expires_at": {
"type": "string",
"format": "date-time",
"description": "Server-owned file deadline: authenticated live/test output expires 365 days after completion; guests expire 72 hours after batch creation."
},
"ai_content": {
"type": "string",
"enum": [
"composite"
],
"description": "Present only when the rendered output contains an owned AI image; the artifact carries composite AI-content metadata."
}
},
"$defs": {
"ListParagraph": {
"type": "object",
"additionalProperties": false,
"required": [
"rune_offset",
"prefix_runes",
"reserve_px",
"continued",
"rtl"
],
"properties": {
"rune_offset": {
"type": "integer",
"minimum": 0,
"description": "Paragraph start in the same final parsed rune stream as wraps, including blank paragraphs."
},
"prefix_runes": {
"type": "integer",
"minimum": 0,
"description": "Drawn marker/indent prefix length; zero for a midparagraph flow continuation."
},
"reserve_px": {
"type": "number",
"description": "Native physical continuation reserve in layout pixels: positive left, negative right, zero centered or unconstrained. Never infer RTL from this sign."
},
"continued": {
"type": "boolean",
"description": "Keeps an earlier paragraph marker reserve without drawing that marker again."
},
"rtl": {
"type": "boolean",
"description": "Original native resolved paragraph direction, including empty and continued paragraphs."
}
},
"description": "Measured list paragraph geometry. Bind it and wraps to unchanged render inputs; ordinary non-list text omits this array. Literal list newlines normalize CRLF/CR to LF before formatting."
},
"PagePreview": {
"type": "object",
"description": "One rasterised page of a finished pdf. A LINK, not base64: an HTTP client can fetch it, and inlining a courtesy picture would add hundreds of kilobytes to every pdf reply. Fetched exactly like result_url; capped on the long side like any preview.",
"properties": {
"page": {
"type": "integer",
"description": "1-based page number of the document."
},
"url": {
"type": "string",
"description": "URL of the stored picture (image/jpeg)."
},
"width": {
"type": "integer",
"description": "Pixel width of the picture as stored, not of the pdf page."
},
"height": {
"type": "integer"
}
}
},
"RenderGeometry": {
"type": "object",
"description": "Geometry of the successful render attempt, bound to job_id and attempt_id. Layout is the DSL coordinate space. Scale layout to pre_finish, map finish.source_rect to finish.destination_rect when present, then scale output to the actual displayed image. Without finish, pre_finish equals output. Display resizing never changes this report. Absent on legacy jobs or document results without raster geometry.",
"required": [
"version",
"job_id",
"attempt_id",
"layout",
"pre_finish",
"output"
],
"properties": {
"version": {
"type": "integer",
"enum": [
1
]
},
"job_id": {
"type": "string",
"minLength": 1
},
"attempt_id": {
"type": "string",
"minLength": 1
},
"layout": {
"$ref": "#/$defs/RenderGeometrySize"
},
"pre_finish": {
"$ref": "#/$defs/RenderGeometrySize"
},
"output": {
"$ref": "#/$defs/RenderGeometrySize"
},
"finish": {
"$ref": "#/$defs/RenderGeometryFinish"
}
}
},
"RenderGeometryFinish": {
"type": "object",
"description": "source_rect is in pre_finish; destination_rect is in output. These rectangles define the transform. source_bounds is diagnostic alpha in pre_finish; artwork_bounds and finished_bounds are diagnostic alpha in output. Alpha bounds never replace the transform.",
"required": [
"profile_id",
"source_rect",
"destination_rect",
"source_bounds",
"artwork_bounds",
"finished_bounds"
],
"properties": {
"profile_id": {
"type": "string",
"minLength": 1
},
"source_rect": {
"$ref": "#/$defs/RenderGeometryRect"
},
"destination_rect": {
"$ref": "#/$defs/RenderGeometryRect"
},
"source_bounds": {
"$ref": "#/$defs/RenderGeometryRect"
},
"artwork_bounds": {
"$ref": "#/$defs/RenderGeometryRect"
},
"finished_bounds": {
"$ref": "#/$defs/RenderGeometryRect"
}
}
},
"RenderGeometryRect": {
"type": "object",
"description": "Half-open integer pixel-edge rectangle. Transform rectangles have positive extents and are contained in their raster space. Diagnostic alpha bounds may be the all-zero rectangle for empty alpha.",
"required": [
"x",
"y",
"width",
"height"
],
"properties": {
"x": {
"type": "integer",
"minimum": 0
},
"y": {
"type": "integer",
"minimum": 0
},
"width": {
"type": "integer",
"minimum": 0
},
"height": {
"type": "integer",
"minimum": 0
}
}
},
"RenderGeometrySize": {
"type": "object",
"description": "Positive raster dimensions in pixels.",
"required": [
"width",
"height"
],
"properties": {
"width": {
"type": "integer",
"minimum": 1
},
"height": {
"type": "integer",
"minimum": 1
}
}
},
"TextDiagnosticOrigin": {
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Server-created prepared structural identity; independent of generated cell IDs."
},
"layer_id": {
"type": "string",
"description": "Safe authored layer identifier; values and paths are excluded."
},
"table": {
"type": "boolean"
},
"master": {
"type": "boolean"
},
"page": {
"type": "integer",
"description": "Final page, 1-based."
},
"row": {
"type": "integer",
"description": "Original body row, 1-based; header and footer row zero."
},
"column": {
"type": "integer",
"description": "Column, 1-based."
},
"header": {
"type": "boolean"
},
"master_kind": {
"type": "string",
"enum": [
"first",
"even"
],
"description": "Present for replacement-master origins in diagnostics v2; keys use master_first/N or master_even/N. Default-only diagnostics remain v1."
},
"footer": {
"type": "boolean",
"description": "True for the final table footer; row is zero and header is false."
}
}
},
"TextFit": {
"type": "object",
"description": "What the finished render MEASURED for one text layer. Every number is in DSL layout coordinates.",
"properties": {
"id": {
"type": "string",
"description": "The measured layer's own id. This is why text_fit is a list: the entry names its layer, the list does not"
},
"plate": {
"$ref": "#/$defs/TextPlateFit",
"description": "Present only for an assembled text plate"
},
"rotation_origin": {
"$ref": "#/$defs/TextRotationOrigin",
"description": "Present for ordinary raster text with rotation or flips; native document text uses its own placement"
},
"raster_top": {
"type": "integer",
"description": "Where the raster image put the top of the text block under vertical_align center or bottom, in whole pixels below the layer's y; absent for top alignment, no box height, a plate, and PDF or HTML output"
},
"size": {
"type": "integer",
"description": "The size that was asked for"
},
"fitted_size": {
"type": "integer",
"description": "The size auto_fit settled on; equal to size when nothing shrank"
},
"text_w": {
"type": "integer",
"description": "Width of the rendered text mask"
},
"text_h": {
"type": "integer",
"description": "Height of the rendered text mask"
},
"box_w": {
"type": "integer",
"description": "Declared layer width; 0 means unconstrained"
},
"box_h": {
"type": "integer",
"description": "Declared layer height; 0 means unconstrained"
},
"lines": {
"type": "integer",
"description": "Lines after wrapping, not only explicit newlines"
},
"wraps": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Where the render broke the text for width: the rune offset, in the text as drawn (variables substituted, list markers and soft hyphens in place, rich_text ** pairs removed), at which each line begins because the line before it was full. A line an explicit newline starts is not listed; absent when nothing wrapped. The editor draws its lines at these offsets"
},
"kept_spaces": {
"type": "array",
"items": {
"type": "integer"
},
"description": "Visible-rune offsets of whitespace replaced with non-breaking spaces by keep_last_words. Shares the wraps coordinate system; absent when no spaces changed. The editor applies these exact substitutions before painting."
},
"mask_x": {
"type": "integer",
"description": "mask_text placement inside a shape or image"
},
"mask_y": {
"type": "integer"
},
"mask_w": {
"type": "integer"
},
"mask_h": {
"type": "integer"
},
"ink_top": {
"type": "integer",
"description": "Mask offset from the logical text box; a diagnostic, not an alignment source — Pango bounds can include empty rows"
},
"ink_left": {
"type": "integer"
},
"fit_group": {
"type": "string",
"description": "The layer's fit_group name, present only for a member of one"
},
"size_alone": {
"type": "integer",
"description": "The size this member would have taken fitted BY ITSELF, before the group levelled. Present only for a member of a fit_group; a layer in no group reports fitted_size and nothing more"
},
"fit_group_size": {
"type": "integer",
"description": "The size the group settled on — the smallest size_alone among its members. A member whose own min_size is above it keeps min_size, so fitted_size can exceed fit_group_size. Present only for a member of a fit_group"
},
"origin": {
"$ref": "#/$defs/TextDiagnosticOrigin"
},
"list_paragraphs": {
"type": "array",
"items": {
"$ref": "#/$defs/ListParagraph"
},
"description": "Native list geometry on the wraps rune coordinate system; includes blank/trailing paragraphs. Absent for ordinary non-list text."
},
"logical_h": {
"type": "integer",
"minimum": 1,
"maximum": 2097151,
"description": "Native logical block height for lists and clip_lines, including blank lines and fallback-font metrics; absent legacy measurements keep existing line-step behavior."
},
"clip_end": {
"type": "integer",
"minimum": 0,
"description": "Exclusive rune endpoint in the final parsed/formatted source, present only when clip_lines removed a suffix. Zero keeps a leading blank line. Slice already parsed styled content before applying wraps/list_paragraphs; this is server observation, never authored DSL."
},
"lines_cut": {
"type": "integer",
"minimum": 0,
"description": "Number of complete native lines removed by clip_lines after full-source fitting. lines is the retained count. Absent when no lines were cut."
}
}
},
"TextPlateFit": {
"type": "object",
"description": "Actual unrotated text plate assembly in DSL pixels, before effects and output scaling. Text coordinates identify the logical text box, not tight glyph bounds.",
"required": [
"x",
"y",
"width",
"height",
"text_x",
"text_y",
"text_width"
],
"properties": {
"x": {
"type": "integer",
"description": "Plate left relative to the layer origin"
},
"y": {
"type": "integer",
"description": "Plate top relative to the layer origin"
},
"width": {
"type": "integer",
"description": "Assembled plate width after minimum size and circle sizing"
},
"height": {
"type": "integer",
"description": "Assembled plate height after minimum size and circle sizing"
},
"text_x": {
"type": "integer",
"description": "Logical text origin inside the plate, including stroke and bearing placement"
},
"text_y": {
"type": "integer",
"description": "Logical text origin inside the plate"
},
"text_width": {
"type": "integer",
"description": "Resolved advance or constrained wrap width"
}
}
},
"TextRotationOrigin": {
"type": "object",
"description": "Actual pre-transform assembly center of ordinary raster text relative to the layer origin, in DSL pixels. Half-pixel centers are preserved.",
"required": [
"x",
"y"
],
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
}
},
"VariableDiagnostic": {
"type": "object",
"description": "One reason a variable does not resolve (spec 007). Names, codes, positions — never a source string, a supplied value or a resolved value.",
"required": [
"code",
"severity"
],
"properties": {
"code": {
"$ref": "#/$defs/VariableDiagnosticCode"
},
"severity": {
"type": "string",
"enum": [
"error",
"warning"
]
},
"variable": {
"type": "string",
"description": "The definition or supplied input the problem belongs to; empty for a context-wide limit."
},
"reference": {
"type": "string",
"description": "The referenced name (unknown_reference, nonnumeric_operand)."
},
"path": {
"type": "array",
"items": {
"type": "string"
},
"description": "A cycle, its first name repeated at the end."
},
"reason": {
"type": "string",
"description": "A stable sub-code: which syntax rule or which limit."
},
"span": {
"type": "object",
"description": "Half-open range of Unicode code points in the definition's source.",
"properties": {
"start": {
"type": "integer"
},
"end": {
"type": "integer"
}
}
}
}
},
"VariableDiagnosticCode": {
"type": "string",
"description": "The stable codes of variable diagnostics (specs/007-nested-variables/contracts/language.md). A diagnostic names the variable, the code, a reason sub-code, the referenced name, a cycle path and a code-point span in the source — never a source string, a supplied value or a result. A schema problem refuses the save (invalid_name, invalid_mode, reserved_name, unsupported_row_scope, source_limit) and nothing is written; a definition that does not resolve from the saved values is saved and named in the save's warnings; at render every unresolvable definition refuses the request before any charge (400, nothing rendered, nothing charged) with the same codes.",
"enum": [
"invalid_name",
"invalid_mode",
"invalid_format",
"invalid_format_value",
"reserved_name",
"unsupported_row_scope",
"unsupported_reference_scope",
"template_syntax",
"formula_syntax",
"unknown_reference",
"cycle",
"nonnumeric_operand",
"division_by_zero",
"numeric_limit",
"source_limit",
"node_limit",
"depth_limit",
"output_limit",
"circular_layout_dependency"
]
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/rendry-io-sync-render-response"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.