URLs
URLs
The layout
/api/v2/schemas/:version/elements/:element_id/icon[.<variant>].svg
| Form | Example | Maps to |
|---|---|---|
icon.svg | /api/v2/schemas/ai@2026-04-16-beta/elements/purpose.example/icon.svg | default variant. |
icon.dark.svg | /api/v2/schemas/ai@2026-04-16-beta/elements/purpose.example/icon.dark.svg | dark variant. |
icon.<context>.svg | /api/v2/schemas/ai@2026-04-16-beta/elements/purpose.example/icon.commercial.svg | Colored variant whose <context> matches a category context.value.id. |
Full URL: prefix with https://api.dtpr.io.
Discovering valid variants
Read the element's icon_variants[] array:
curl -s https://api.dtpr.io/api/v2/schemas/ai@2026-04-16-beta/elements/purpose.example \
| jq '.element.icon_variants'
# [ "default", "dark", "commercial", "civic" ]
Or use get_icon_url — it returns both the URL and the full variant list in one call, and emits unknown_variant errors with valid_variants in fix_hint when you ask for an invalid one.
Validation
The server rejects ids outside [a-zA-Z0-9_-] with HTTP 400 bad_request:
{
"ok": false,
"errors": [
{ "code": "bad_request", "message": "Invalid element_id '…'.", "fix_hint": "Use [a-zA-Z0-9_-] only." }
]
}
Unknown version, element, or variant returns HTTP 404 not_found; the unknown_variant variant includes the valid list in its fix_hint.
Fallback
The route first attempts a pre-baked R2 point-read. On miss, it logs an icon_miss_fallback structured event and composes the SVG on the fly with the same pure compositor. The response is byte-identical to the pre-baked path — consumers never see a degraded fallback. Only Cache-Control max-age differs (60 s on a beta miss versus 3600 s on a beta hit).
MCP equivalent
get_icon_url returns the URL as a relative string (/api/v2/...). Prefix https://api.dtpr.io when fetching.
{
"data": {
"url": "/api/v2/schemas/ai@2026-04-16-beta/elements/purpose.example/icon.dark.svg",
"content_type": "image/svg+xml",
"variant": "dark",
"valid_variants": ["default", "dark", "commercial", "civic"]
}
}