render_pdf. Do not rename render_pdf. Fill is a second verb: inspect names, map values, dry-run, then fill.
Same bp_ key (or the same OAuth credential) as render. Do not mint a fill key. fill_form spends 1 unit. inspect_form and validate_fill do not.
Published skill: fill-form. Markdown → PDF remains render-pdf.
Loop
/NeedAppearances. Do not claim a fill succeeded when the tool errored.
1
Stage or store the blank
A small PDF can go in
pdf as Base64. A large form should use upload_template (same chunked path as upload_image) and pass the blink://staged/… handle as pdf. That handle is not a templateId and is not the account library.To fill the same blank many times, call store_template (pdf + title) and keep the returned id. store_template already returns fields.2
Inspect
Call
inspect_form with pdf (Base64 or blink://staged). Read fields[].name and kind. No unit. Does not store. MCP inspect_form and validate_fill do not accept templateId — for a stored blank, use the fields from store_template / get_template.3
Map values
Build
{ "givenName": "Ada", "agree": true } from those names. Omitted names stay unchanged. false is a value.4
Validate
Call
validate_fill with the same pdf (bytes or staged handle) and values. Read written and missingRequired, or fix named errors. No download. No unit. Does not accept templateId or flatten.5
Fill
Call
fill_form with pdf XOR templateId and values. It returns a signed /d/:token — never raw PDF bytes. 1 unit. Appearances are written. Optional flatten: true stamps and strips widgets; default overlay keeps them. Optional persist: true keeps the file (MCP only; REST POST /v1/fill rejects persist).x-idempotency-key from the fill-body fingerprint (same seam as render_pdf). The agent does not invent a key. A retry of the same template and values does not spend a second unit. Changed values are a new fill.
Tools
list_pdfs, persist_pdf, and delete_pdf apply to filled (and rendered) outputs the same way as after render_pdf. They are not the template library.
inspect_form / validate_fill / fill_form map REST 429 to the same rate_limited envelope as render_pdf.
REST
POST /v1/inspect, POST /v1/validate-fill, and POST /v1/fill all accept templateId XOR pdf. On MCP, only fill_form takes templateId. Stage a one-off form with upload_template; keep a reusable blank with store_template.After every fill
- Read
warningson the result. A too-long text field can still return a PDF and nameoverflow.clipped. - The download URL expires in 24 hours (
expiresAt). Default storage is 24-hour ephemeral.persist: trueorpersist_pdfkeeps the object; the link still expires in 24 hours — calllist_pdfsfor a fresh URL. - Present the delivery receipt verbatim. Do not claim success when the tool errored.
REST vs MCP
Connect a client with the same steps as Connect a Client. The Cursor
mcp.json (and Claude .mcp.json) is one paste with the same bp_ key as render_pdf — the tool list includes inspect_form and fill_form. No extra OAuth step and no pdf:fill scope. Then ask: “Inspect this form, fill givenName with Ada and agree with true, and give me the download link.”