Skip to main content
A signed document with no signature is not a signed record. Binding an image — a logo, a photo, a rasterized signature — has two constraints you must design around: an ingress validation rule and a pipeline capability.

Constraint 1 — image variables accept URLs, not base64

A variable with dataType: "image" (or "url") is validated as z.string().url() at the render endpoint. A data:image/png;base64,… value fails that check and the render is rejected with invalid_input_data. So an image variable must carry an http(s) URL.

Constraint 2 — the signature block is text-only

The dedicated signature block renders a line plus name/date text — it has no image slot on any pipeline. A signature image must therefore be modeled as a separate image variable, not the signature block. And document-mode image blocks are static (they render the builder’s src, never your data), so a data-bound image needs the Canvas or PDF overlay pipeline — see Render pipelines. The portable approach that works within the current validation:
1

Author on a data-binding pipeline

Use Canvas (Handlebars) with an image variable bound to an image node, or PDF overlay with an image field. Document mode will not render a data-bound image.
2

Host the rasterized image

Upload the signature/image to your own bucket or CDN and get an https URL. (There is no non-embed, key-authenticated upload endpoint — see below.)
3

Pass the URL as an image variable

{
  "data": {
    "handover": { "signedBy": "Jane Doe" },
    "signatureImageUrl": "https://cdn.example.com/sig/abc.png"
  }
}

Alternative: inline base64 without external hosting

If you cannot host the image, you can send it inline — but not as an image/url variable (those reject data-URIs). Declare the field as dataType: "text" so any string passes validation, then render it as an image on a pipeline that accepts a data-URI source:
  • Canvas (Handlebars): the HTML compiler accepts data:image/... image sources.
  • PDF overlay: the pdfme image field accepts a base64 data-URI.
{ "data": { "signatureData": "data:image/png;base64,iVBORw0KGgo..." } }
Declaring the field as text means you lose URL validation — the template must be authored to render that variable as an image (an image node bound to the key, or a pdfme image field). Pick one mechanism per field and document it with the template.

Why there is no headless upload endpoint

The only image-upload endpoint today is embed-session-scoped (fill-mode sessions only) and is not reachable with a plain ck_live_ key on a headless path. For server-to-server flows, host the image yourself and pass a URL, or use the inline base64 alternative above. A key-authenticated, non-embed upload endpoint is on the roadmap.