Create report template
const url = 'https://example.com/api/v1/org/example/ws/example/airt/projects/example/templates';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"config":{"components":[{"content":"example","id":"example","instructions":"example","type":"title"}],"format":"pdf","schema_version":1,"style":{"font":"Helvetica","font_size":11}},"description":"example","name":"example","preset":{"branding":{"company_name":"example","confidentiality_footer":"example","logo_oid":"example","report_title":"example"},"compliance_frameworks":["owasp_llm_top_10"],"filters":{"assessment_ids":["2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"],"attack_name":["example"],"category":["example"],"finding_type":["jailbreak"],"include_undated_assessments":false,"min_score":1,"severity":["critical"],"started_after":"2026-04-15T12:00:00Z","started_before":"2026-04-15T12:00:00Z"},"format":"pdf","include_adversarial":false,"sections":["risk_score_metrics"],"style":{"font":"Helvetica","font_size":11}}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/api/v1/org/example/ws/example/airt/projects/example/templates \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "config": { "components": [ { "content": "example", "id": "example", "instructions": "example", "type": "title" } ], "format": "pdf", "schema_version": 1, "style": { "font": "Helvetica", "font_size": 11 } }, "description": "example", "name": "example", "preset": { "branding": { "company_name": "example", "confidentiality_footer": "example", "logo_oid": "example", "report_title": "example" }, "compliance_frameworks": [ "owasp_llm_top_10" ], "filters": { "assessment_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ], "attack_name": [ "example" ], "category": [ "example" ], "finding_type": [ "jailbreak" ], "include_undated_assessments": false, "min_score": 1, "severity": [ "critical" ], "started_after": "2026-04-15T12:00:00Z", "started_before": "2026-04-15T12:00:00Z" }, "format": "pdf", "include_adversarial": false, "sections": [ "risk_score_metrics" ], "style": { "font": "Helvetica", "font_size": 11 } } }'Create a saved report template. Supply preset (server expands it to a component tree) XOR config (frontend-authored tree). Returns 409 if the project already has the per-project cap of templates or if name is already in use in this project.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Organization slug
Organization slug
Workspace slug
Workspace slug
Project slug or UUID
Project slug or UUID
Request Body required
Section titled “Request Body required ”Request body for POST .../templates.
Exactly one of preset (server expands to component tree) or config
(advanced path — caller supplies the component tree directly).
object
Shape stored inside airt_report_templates.config (JSONB).
Directly maps to a DreadReport invocation:
DreadReport(*components).style(**style.model_dump()).to_
object
Text-bearing component. Covers DreadReport Title, Authors, Text.
Exactly one of content (static) or instructions (AI-writer prompt)
must be set. MVP renderer ignores instructions and will error on any
component that relies on it — full support lands with the DreadReport
adapter (see ENG-6485).
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.Table.
DreadReport accepts inline data (dict/list/DataFrame); we add AIRT query
sources via the discriminated union TableDataSource. StaticTableSource
is the DreadReport-equivalent inline path.
object
AIRT findings — filtered rows.
include_adversarial opts the sensitive best_* adversarial-prompt fields
(best_candidate, best_response, best_transformed_prompt,
best_judge_reasoning) into the resolved rows and the rendered output
. It is a per-build decision and is intentionally NOT persisted
into saved template configs — derive_preset_from_components resets it and
template save strips it — so a stored template can never silently re-emit
adversarial content on every future build. Defaults False; the default path
leaves both the resolver projection and every renderer byte-for-byte
unchanged.
object
Filter over findings rows. All strings untrusted.
Scope: these fields narrow the findings table rows only. Report-wide assessment scoping (narrow ASR / severity / metrics sections by the same assessment subset) is a follow-up — see ENG-6432 PR description. For Phase 1 the UI-surfaced assessment/date filters apply only to the findings table component.
object
object
object
asr_by_transform from analytics_snapshot — PRD ‘Transform Effectiveness’.
object
severity_breakdown from analytics_snapshot — PRD ‘Severity Breakdown’.
object
Scalar risk metrics (risk_score, overall_asr, totals) as metric/value rows. PRD ‘Risk Score & ASR Metrics’.
object
Distinct target/attacker/judge models across selected assessments.
PRD ‘Models Used’. include picks which model roles to surface; default
covers all three.
object
object
Inline rows — DreadReport-native data: list[dict] shape.
Security: row / key / cell caps guard against payload DoS. Strings are
length-capped at MAX_STATIC_CELL_LEN. Numeric types are unbounded but
JSONB encoding caps practical size.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Header and Footer.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.containers.Section / References / Appendix.
preset_key is an optional tag set by build_airt_components when the
section was generated from an AirtPresetRequest checkbox. The renderer’s
EmptyReportSectionError echoes this back so the frontend can re-enable
the exact checkbox the user toggled. Template-authored sections (arbitrary
trees, no preset origin) leave it None — the frontend falls back to
title-only messaging for those.
object
Text-bearing component. Covers DreadReport Title, Authors, Text.
Exactly one of content (static) or instructions (AI-writer prompt)
must be set. MVP renderer ignores instructions and will error on any
component that relies on it — full support lands with the DreadReport
adapter (see ENG-6485).
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.Table.
DreadReport accepts inline data (dict/list/DataFrame); we add AIRT query
sources via the discriminated union TableDataSource. StaticTableSource
is the DreadReport-equivalent inline path.
object
AIRT findings — filtered rows.
include_adversarial opts the sensitive best_* adversarial-prompt fields
(best_candidate, best_response, best_transformed_prompt,
best_judge_reasoning) into the resolved rows and the rendered output
. It is a per-build decision and is intentionally NOT persisted
into saved template configs — derive_preset_from_components resets it and
template save strips it — so a stored template can never silently re-emit
adversarial content on every future build. Defaults False; the default path
leaves both the resolver projection and every renderer byte-for-byte
unchanged.
object
Filter over findings rows. All strings untrusted.
Scope: these fields narrow the findings table rows only. Report-wide assessment scoping (narrow ASR / severity / metrics sections by the same assessment subset) is a follow-up — see ENG-6432 PR description. For Phase 1 the UI-surfaced assessment/date filters apply only to the findings table component.
object
object
object
asr_by_transform from analytics_snapshot — PRD ‘Transform Effectiveness’.
object
severity_breakdown from analytics_snapshot — PRD ‘Severity Breakdown’.
object
Scalar risk metrics (risk_score, overall_asr, totals) as metric/value rows. PRD ‘Risk Score & ASR Metrics’.
object
Distinct target/attacker/judge models across selected assessments.
PRD ‘Models Used’. include picks which model roles to surface; default
covers all three.
object
object
Inline rows — DreadReport-native data: list[dict] shape.
Security: row / key / cell caps guard against payload DoS. Strings are
length-capped at MAX_STATIC_CELL_LEN. Numeric types are unbounded but
JSONB encoding caps practical size.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Header and Footer.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Recursive reference to SectionComponent-Input.
object
Document-wide style. Mirrors DreadReport.style() — font, font_size.
Fonts locked to the ReportLab built-in set (no file I/O at render time).
object
Simple AIRT-report request — what the frontend POSTs for template create
or inline build. Server expands to ReportTemplateSchema via
build_airt_components.
object
Optional branding slots. Expanded into Header/Footer/Title by the preset builder. Frontend-facing only — no direct DreadReport equivalent, but the expansion produces DreadReport-valid components.
Filter over findings rows. All strings untrusted.
Scope: these fields narrow the findings table rows only. Report-wide assessment scoping (narrow ASR / severity / metrics sections by the same assessment subset) is a follow-up — see ENG-6432 PR description. For Phase 1 the UI-surfaced assessment/date filters apply only to the findings table component.
object
Document-wide style. Mirrors DreadReport.style() — font, font_size.
Fonts locked to the ReportLab built-in set (no file I/O at render time).
object
Responses
Section titled “ Responses ”Successful Response
API response shape for a saved report template.
preset is derived best-effort from config via
derive_preset_from_components. It’s None for templates authored via
raw config= rather than a preset (no SectionComponent.preset_key
tags to read). The Phase 2 frontend uses preset to back-fill the form
when a saved template is selected.
object
Shape stored inside airt_report_templates.config (JSONB).
Directly maps to a DreadReport invocation:
DreadReport(*components).style(**style.model_dump()).to_
object
Text-bearing component. Covers DreadReport Title, Authors, Text.
Exactly one of content (static) or instructions (AI-writer prompt)
must be set. MVP renderer ignores instructions and will error on any
component that relies on it — full support lands with the DreadReport
adapter (see ENG-6485).
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.Table.
DreadReport accepts inline data (dict/list/DataFrame); we add AIRT query
sources via the discriminated union TableDataSource. StaticTableSource
is the DreadReport-equivalent inline path.
object
AIRT findings — filtered rows.
include_adversarial opts the sensitive best_* adversarial-prompt fields
(best_candidate, best_response, best_transformed_prompt,
best_judge_reasoning) into the resolved rows and the rendered output
. It is a per-build decision and is intentionally NOT persisted
into saved template configs — derive_preset_from_components resets it and
template save strips it — so a stored template can never silently re-emit
adversarial content on every future build. Defaults False; the default path
leaves both the resolver projection and every renderer byte-for-byte
unchanged.
object
Filter over findings rows. All strings untrusted.
Scope: these fields narrow the findings table rows only. Report-wide assessment scoping (narrow ASR / severity / metrics sections by the same assessment subset) is a follow-up — see ENG-6432 PR description. For Phase 1 the UI-surfaced assessment/date filters apply only to the findings table component.
object
object
object
asr_by_transform from analytics_snapshot — PRD ‘Transform Effectiveness’.
object
severity_breakdown from analytics_snapshot — PRD ‘Severity Breakdown’.
object
Scalar risk metrics (risk_score, overall_asr, totals) as metric/value rows. PRD ‘Risk Score & ASR Metrics’.
object
Distinct target/attacker/judge models across selected assessments.
PRD ‘Models Used’. include picks which model roles to surface; default
covers all three.
object
object
Inline rows — DreadReport-native data: list[dict] shape.
Security: row / key / cell caps guard against payload DoS. Strings are
length-capped at MAX_STATIC_CELL_LEN. Numeric types are unbounded but
JSONB encoding caps practical size.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Header and Footer.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.containers.Section / References / Appendix.
preset_key is an optional tag set by build_airt_components when the
section was generated from an AirtPresetRequest checkbox. The renderer’s
EmptyReportSectionError echoes this back so the frontend can re-enable
the exact checkbox the user toggled. Template-authored sections (arbitrary
trees, no preset origin) leave it None — the frontend falls back to
title-only messaging for those.
object
Text-bearing component. Covers DreadReport Title, Authors, Text.
Exactly one of content (static) or instructions (AI-writer prompt)
must be set. MVP renderer ignores instructions and will error on any
component that relies on it — full support lands with the DreadReport
adapter (see ENG-6485).
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.Table.
DreadReport accepts inline data (dict/list/DataFrame); we add AIRT query
sources via the discriminated union TableDataSource. StaticTableSource
is the DreadReport-equivalent inline path.
object
AIRT findings — filtered rows.
include_adversarial opts the sensitive best_* adversarial-prompt fields
(best_candidate, best_response, best_transformed_prompt,
best_judge_reasoning) into the resolved rows and the rendered output
. It is a per-build decision and is intentionally NOT persisted
into saved template configs — derive_preset_from_components resets it and
template save strips it — so a stored template can never silently re-emit
adversarial content on every future build. Defaults False; the default path
leaves both the resolver projection and every renderer byte-for-byte
unchanged.
object
Filter over findings rows. All strings untrusted.
Scope: these fields narrow the findings table rows only. Report-wide assessment scoping (narrow ASR / severity / metrics sections by the same assessment subset) is a follow-up — see ENG-6432 PR description. For Phase 1 the UI-surfaced assessment/date filters apply only to the findings table component.
object
object
object
asr_by_transform from analytics_snapshot — PRD ‘Transform Effectiveness’.
object
severity_breakdown from analytics_snapshot — PRD ‘Severity Breakdown’.
object
Scalar risk metrics (risk_score, overall_asr, totals) as metric/value rows. PRD ‘Risk Score & ASR Metrics’.
object
Distinct target/attacker/judge models across selected assessments.
PRD ‘Models Used’. include picks which model roles to surface; default
covers all three.
object
object
Inline rows — DreadReport-native data: list[dict] shape.
Security: row / key / cell caps guard against payload DoS. Strings are
length-capped at MAX_STATIC_CELL_LEN. Numeric types are unbounded but
JSONB encoding caps practical size.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Header and Footer.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Mirrors dreadreport.report.components.Image. fp is an S3 OID.
Mirrors dreadreport.report.components.PageNumber.
object
Recursive reference to SectionComponent-Output.
object
Document-wide style. Mirrors DreadReport.style() — font, font_size.
Fonts locked to the ReportLab built-in set (no file I/O at render time).
object
Simple AIRT-report request — what the frontend POSTs for template create
or inline build. Server expands to ReportTemplateSchema via
build_airt_components.
object
Optional branding slots. Expanded into Header/Footer/Title by the preset builder. Frontend-facing only — no direct DreadReport equivalent, but the expansion produces DreadReport-valid components.
Filter over findings rows. All strings untrusted.
Scope: these fields narrow the findings table rows only. Report-wide assessment scoping (narrow ASR / severity / metrics sections by the same assessment subset) is a follow-up — see ENG-6432 PR description. For Phase 1 the UI-surfaced assessment/date filters apply only to the findings table component.
object
Document-wide style. Mirrors DreadReport.style() — font, font_size.
Fonts locked to the ReportLab built-in set (no file I/O at render time).
object
Example
{ "config": { "components": [ { "type": "title" } ], "format": "pdf", "schema_version": 1, "style": { "font": "Helvetica", "font_size": 11 } }, "preset": { "compliance_frameworks": [ "owasp_llm_top_10" ], "filters": { "finding_type": [ "jailbreak" ], "include_undated_assessments": false, "severity": [ "critical" ] }, "format": "pdf", "include_adversarial": false, "sections": [ "risk_score_metrics" ], "style": { "font": "Helvetica", "font_size": 11 } }}Invalid request
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Authentication failed
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Access forbidden
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Not found
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Already exists
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Validation error
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Upgrade required
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Rate limited
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Internal server error
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Bad gateway
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}Gateway timeout
Canonical API error envelope returned by the API.
object
HTTP status code
Human-readable error message
object
Where the validation error occurred
Human-readable validation message
Machine-readable validation error type
Stable machine-readable error type
Example
{ "code": 401, "detail": "Authentication failed", "type": "authentication_error"}