Delivery URLs

GET  https://cdn.picsoar.com/v1/:projectKey/:preset/*sourcePath?v=token
HEAD https://cdn.picsoar.com/v1/:projectKey/:preset/*sourcePath?v=token

Source path rules

The path is validated before any network call. It must:

Anything else is a 400 with the reason in x-picsoar-reason. The extension allowlist is a security control, not a convenience: without it the endpoint would stream any file at your origin through our CDN.

Query parameters

Exactly one is accepted: v, matching [A-Za-z0-9._~-]{1,64}. Any other parameter is rejected, not ignored.

Ignoring unknown parameters sounds harmless and is not: ?a=1 through?a=1000000 would be a million cache entries and a million transformations, mintable by anyone with a for-loop.

Cache key

A derivative is stored under:

k1 / projectKey / e{cacheEpoch} / preset@version / format / v{token} / encodedPath

Each component is there for a reason:

Changing this format is a breaking change: every existing derivative becomes unreachable and re-transforms on first request. It is gated behind explicit approval in CI.

Response headers

HeaderMeaning
x-picsoar-presetPreset and version applied, e.g. card@1.
x-picsoar-formatwebp, avif, or source.
x-picsoar-decisionWhy that format: accept-webp, resize-only, transform-failed, quota-degraded, source-too-large
x-picsoar-cachehit or miss.
x-picsoar-reasonPresent only on rejections and errors.
x-request-idQuote this in support requests.

Cache-Control we set