MCP server
The tools squiggli gives AI agents, generated from the server itself.
squiggli is a remote MCP server at https://squiggli.billy-965.workers.dev/mcp (Streamable HTTP). Connect with an API key as a bearer token, or with OAuth. Setup for each AI is in Connect your AI. Every tool calls the same API as your code does, so its errors and limits are the same.
Tools
| Tool | Use it when |
|---|---|
squiggli_send_for_signature | Use when the user wants someone to sign a document now: a PDF (documents[].file_base64 or file_url) or a saved template (template_id + variables). Emails each signer a link unless delivery is "link". Set test: true while building or trying things (free, watermarked). Live documents cost $1.00 each ($1.50 white-labelled), after the free ones. Signers with no fields get a signature page added automatically. |
squiggli_create_draft_envelope | Use when the user wants to prepare a document to review before sending. Same input as squiggli_send_for_signature; send it later with squiggli_send_envelope. |
squiggli_send_envelope | Use when a draft envelope is ready to go out to its signers. |
squiggli_get_envelope_status | Use when the user asks whether a document has been opened or signed. Returns the status, each signer's status, when they opened it and from which link (invite, reminder, resend), every field and its value, the deadline and the reminder settings. |
squiggli_list_envelopes | Use when the user wants to see their documents, e.g. everything still waiting for signatures (status "sent,viewed"). |
squiggli_get_envelope_activity | Use when the user wants the full history of a document: every send, open (with IP and device), reminder, signature, decline and void, in order. |
squiggli_remind_signers | Use when the user wants to nudge people who haven't signed. Emails each one a fresh link (at most once an hour per signer). |
squiggli_update_envelope | Use when the user wants to extend or move a signing deadline, change reminders or metadata, or (for drafts) the title and message. |
squiggli_void_envelope | Use when the user wants to cancel a document that has been sent but not completed. Signers are told it was cancelled. This cannot be undone. |
squiggli_get_signed_document | Use when everyone has signed and the user wants the signed PDF or the completion certificate. Returns download links that work for a week. |
squiggli_list_templates | Use when the user wants to send a standard document (a quote, lease, NDA) and you need its template_id, roles and variables. |
squiggli_get_template | Use when you need a template's full content, roles and {{variables}} before sending it or editing it. |
squiggli_list_starter_templates | Use before creating a template, to start from a polished design instead of a blank page: statement of work (cover page with a photo, Poppins and Roboto, both parties signing side by side), quote, mutual NDA, service agreement. Returns each design's full blocks and theme, which you can copy and change. |
squiggli_create_template | Use when the user wants a reusable, well-designed document (proposal, statement of work, quote, contract). Quickest: { "starter": "statement-of-work", "name": "..." } then change what you need. Or write blocks: cover (full-page title page with optional photo and logo), heading, paragraph (**bold**, *italic*, \n), details (label: value lines), callout (tinted note), table, list, image, divider, spacer, page_break, columns (2 or 3 side by side, e.g. the two parties above their signatures), field and signature (each names the signer role that fills it). theme sets the look: font and heading_font (inter, roboto, poppins, montserrat, open-sans, lora, merriweather, playfair-display, instrument-sans, familjen-grotesk, helvetica), text_color, heading_color, accent_color (hex), font_size, line_height, page_size, margin, header_logo. Put {{variables}} in any text for what changes per send. Afterwards call squiggli_preview_template and give the user the link so they can see it. |
squiggli_preview_template | Use when you have created or changed a template and the user should see it. Returns a link to the PDF (valid for an hour), filled with any variables you pass. Show the link to the user. |
squiggli_upload_image | Use when a template needs an image squiggli can't download itself (a logo or cover photo the user gave you). Send a PNG or JPEG as base64, or an https URL. Returns an asset id to put in an image block's url or a cover's image_url. |
squiggli_update_template | Use when the user wants to change a template: wording, layout or look. Send only what changes: theme merges with the current theme, blocks replaces all the blocks. Then call squiggli_preview_template. |
squiggli_create_webhook | Use when the user's app needs to know when documents are viewed, signed or completed. Returns a signing secret, shown once: store it and check the Squiggli-Signature header. |
squiggli_list_webhooks | Use when you need to check which URLs get squiggli events. |
squiggli_create_api_key | Use when you are adding squiggli to the user's app and it needs its own key (put it in the app's environment as SQUIGGLI_API_KEY, never in code). mode test for development. Shown once. |
squiggli_create_embed_token | Use when the user's web app should show squiggli's template editor or one envelope inside its own pages. Returns a short-lived token and an iframe URL. |
squiggli_get_account | Use when you need to know whether this business can send live documents yet, how many free documents are left, and its prices. If it can't send, give the user add_card_url. |
squiggli_get_usage | Use when the user asks how many documents they have sent or what this month costs. Billed on their Kiewa statement. |
squiggli_get_integration_guide | Use before writing code that adds squiggli to the user's app. Returns a complete, copy-ready guide for their stack: sending, embedded signing, webhooks with signature checks, and test mode. |
Tool inputs
squiggli_send_for_signature
Send a document for signing.
| Input | Type | Description |
|---|---|---|
title required | string | What signers see, e.g. "Harbour Lane lease, unit 4". |
message | string | A note to signers, shown in the email and on the signing page. |
documents | array of object | |
documents[].name | string | File name shown to signers. Defaults to the template name or "Document 1". |
documents[].file_base64 | string | A PDF, base64-encoded. Up to 10 MB. |
documents[].file_url | string | An https link squiggli downloads the PDF from (up to 10 MB). |
documents[].template_id | string | Render this template (tpl_...) as the document. |
documents[].variables | object | Values for the template's {{variables}}, e.g. {"client.name": "Ava Chen", "rent": "$650 a week"}. |
template_id | string | Shortcut for documents: [{ template_id, variables }]. |
variables | object | Values for the template's {{variables}}, e.g. {"client.name": "Ava Chen", "rent": "$650 a week"}. |
signers required | array of object | |
signers[].name required | string | |
signers[].email | string | Required when delivery is email. |
signers[].role | string | The template role this signer fills, e.g. "tenant". Without roles, signers fill the template's roles in order. |
signers[].delivery | "email" | "link" | email: squiggli emails the signing link and reminders. link: no emails; show signing_url yourself or embed it. |
signers[].order | integer | Signing order when signing_order is sequential (1 signs first). Defaults to list order. |
signers[].access_code | string | A code the signer must enter before they can see the document. Give it to them another way (phone, SMS, in person): it identifies them by more than the link. Recommended for delivery "link". |
fields | array of object | |
fields[].signer required | integer or string | Which signer fills it: their index in signers[] (0 is the first), their role, or their email. |
fields[].document | integer | Index into documents[]. Default 0. |
fields[].type required | "signature" | "initials" | "date_signed" | "name" | "email" | "text" | "checkbox" | |
fields[].page required | integer | 1 is the first page. |
fields[].x required | number | PDF points from the left edge of the page (A4 is 595 x 842 points). |
fields[].y required | number | PDF points from the top edge of the page. |
fields[].width | number | Points. Defaults by type: signature 200, initials 60, checkbox 14, others 160. |
fields[].height | number | Points. Defaults by type: signature 50, initials 32, checkbox 14, others 22. |
fields[].required | boolean | Default true, except checkboxes. |
fields[].label | string | |
fields[].key | string | Your own name for the field. Returned with its value in GET /v1/envelopes/{id}. |
fields[].value | string | Prefill a text field. The signer can change it. |
signing_order | "parallel" | "sequential" | parallel: everyone gets it at once. sequential: one after another, by order. |
deadline | string | Signing deadline (ISO 8601). After it the envelope expires. |
deadline_days | integer | Deadline as days from sending, instead of deadline. |
reminders | false or object | Automatic reminder emails. false turns them off. |
reminders.every_days | integer or null | Remind unsigned signers every N days. null for none. Default 3. |
reminders.before_deadline_days | array of integer | Also remind this many days before the deadline. Default [1]. |
reminders.max | integer | At most this many reminders per signer. Default 5. |
test | boolean | Test envelope: free and unlimited, watermarked "TEST - NOT LEGALLY BINDING". Always true with a sq_test_ key. |
whitelabel | boolean | No squiggli name or footer anywhere signers look: your business's name and colour only. $1.50 instead of $1.00. |
sender | object | Who signers are told sent it ("Ava Chen sent you..."), and who gets the decline and completed emails. Defaults to the business. |
sender.name required | string | |
sender.email | string | |
metadata | object | Your own key-value data (up to 20 keys), e.g. {"job_id": "J-1042"}. Returned with the envelope and in webhooks. |
redirect_url | string | Where the signing page sends a signer after they sign. |
squiggli_create_draft_envelope
Create a draft envelope.
| Input | Type | Description |
|---|---|---|
title required | string | What signers see, e.g. "Harbour Lane lease, unit 4". |
message | string | A note to signers, shown in the email and on the signing page. |
documents | array of object | |
documents[].name | string | File name shown to signers. Defaults to the template name or "Document 1". |
documents[].file_base64 | string | A PDF, base64-encoded. Up to 10 MB. |
documents[].file_url | string | An https link squiggli downloads the PDF from (up to 10 MB). |
documents[].template_id | string | Render this template (tpl_...) as the document. |
documents[].variables | object | Values for the template's {{variables}}, e.g. {"client.name": "Ava Chen", "rent": "$650 a week"}. |
template_id | string | Shortcut for documents: [{ template_id, variables }]. |
variables | object | Values for the template's {{variables}}, e.g. {"client.name": "Ava Chen", "rent": "$650 a week"}. |
signers required | array of object | |
signers[].name required | string | |
signers[].email | string | Required when delivery is email. |
signers[].role | string | The template role this signer fills, e.g. "tenant". Without roles, signers fill the template's roles in order. |
signers[].delivery | "email" | "link" | email: squiggli emails the signing link and reminders. link: no emails; show signing_url yourself or embed it. |
signers[].order | integer | Signing order when signing_order is sequential (1 signs first). Defaults to list order. |
signers[].access_code | string | A code the signer must enter before they can see the document. Give it to them another way (phone, SMS, in person): it identifies them by more than the link. Recommended for delivery "link". |
fields | array of object | |
fields[].signer required | integer or string | Which signer fills it: their index in signers[] (0 is the first), their role, or their email. |
fields[].document | integer | Index into documents[]. Default 0. |
fields[].type required | "signature" | "initials" | "date_signed" | "name" | "email" | "text" | "checkbox" | |
fields[].page required | integer | 1 is the first page. |
fields[].x required | number | PDF points from the left edge of the page (A4 is 595 x 842 points). |
fields[].y required | number | PDF points from the top edge of the page. |
fields[].width | number | Points. Defaults by type: signature 200, initials 60, checkbox 14, others 160. |
fields[].height | number | Points. Defaults by type: signature 50, initials 32, checkbox 14, others 22. |
fields[].required | boolean | Default true, except checkboxes. |
fields[].label | string | |
fields[].key | string | Your own name for the field. Returned with its value in GET /v1/envelopes/{id}. |
fields[].value | string | Prefill a text field. The signer can change it. |
signing_order | "parallel" | "sequential" | parallel: everyone gets it at once. sequential: one after another, by order. |
deadline | string | Signing deadline (ISO 8601). After it the envelope expires. |
deadline_days | integer | Deadline as days from sending, instead of deadline. |
reminders | false or object | Automatic reminder emails. false turns them off. |
reminders.every_days | integer or null | Remind unsigned signers every N days. null for none. Default 3. |
reminders.before_deadline_days | array of integer | Also remind this many days before the deadline. Default [1]. |
reminders.max | integer | At most this many reminders per signer. Default 5. |
test | boolean | Test envelope: free and unlimited, watermarked "TEST - NOT LEGALLY BINDING". Always true with a sq_test_ key. |
whitelabel | boolean | No squiggli name or footer anywhere signers look: your business's name and colour only. $1.50 instead of $1.00. |
sender | object | Who signers are told sent it ("Ava Chen sent you..."), and who gets the decline and completed emails. Defaults to the business. |
sender.name required | string | |
sender.email | string | |
metadata | object | Your own key-value data (up to 20 keys), e.g. {"job_id": "J-1042"}. Returned with the envelope and in webhooks. |
redirect_url | string | Where the signing page sends a signer after they sign. |
squiggli_send_envelope
Send a draft.
| Input | Type | Description |
|---|---|---|
envelope_id required | string | The envelope (env_...) id |
squiggli_get_envelope_status
Get envelope status.
| Input | Type | Description |
|---|---|---|
envelope_id required | string | The envelope (env_...) id |
squiggli_list_envelopes
List envelopes.
| Input | Type | Description |
|---|---|---|
status | string | Comma-separated: draft, sent, viewed, signed, declined, voided, expired |
test | boolean | |
limit | integer | |
cursor | string | next_cursor from the previous page |
squiggli_get_envelope_activity
Get the audit trail.
| Input | Type | Description |
|---|---|---|
envelope_id required | string | The envelope id |
squiggli_remind_signers
Remind signers.
| Input | Type | Description |
|---|---|---|
envelope_id required | string | The envelope id |
signer_ids | array of string | Default: everyone whose turn it is. |
squiggli_update_envelope
Change deadline, reminders or details.
| Input | Type | Description |
|---|---|---|
title | string | |
message | string or null | |
deadline | string or null | Move or clear the deadline. Works on sent envelopes too. |
reminders | false or object | Automatic reminder emails. false turns them off. |
reminders.every_days | integer or null | Remind unsigned signers every N days. null for none. Default 3. |
reminders.before_deadline_days | array of integer | Also remind this many days before the deadline. Default [1]. |
reminders.max | integer | At most this many reminders per signer. Default 5. |
metadata | object | Your own key-value data (up to 20 keys), e.g. {"job_id": "J-1042"}. Returned with the envelope and in webhooks. |
redirect_url | string or null | |
envelope_id required | string |
squiggli_void_envelope
Cancel a sent envelope.
| Input | Type | Description |
|---|---|---|
envelope_id required | string | The envelope id |
reason | string |
squiggli_get_signed_document
Get the signed PDF.
| Input | Type | Description |
|---|---|---|
envelope_id required | string | The envelope id |
squiggli_list_templates
List templates.
No inputs.
squiggli_get_template
Get template.
| Input | Type | Description |
|---|---|---|
template_id required | string | The template (tpl_...) id |
squiggli_list_starter_templates
List starter designs.
No inputs.
squiggli_create_template
Create template.
| Input | Type | Description |
|---|---|---|
name | string | Required unless you use a starter (its name is the default). |
description | string | |
starter | string | Start from a ready-made design (GET /v1/templates/starters), e.g. "statement-of-work". Anything else you send overrides it. |
theme | object | How the document looks. Every setting is optional. |
theme.font | "helvetica" | "inter" | "roboto" | "poppins" | "montserrat" | "open-sans" | "lora" | "merriweather" | "playfair-display" | "instrument-sans" | "familjen-grotesk" | Body font. Default helvetica. |
theme.heading_font | "helvetica" | "inter" | "roboto" | "poppins" | "montserrat" | "open-sans" | "lora" | "merriweather" | "playfair-display" | "instrument-sans" | "familjen-grotesk" | Heading and cover title font. Default: the body font. |
theme.text_color | string | Body text. Default #141a2e. |
theme.heading_color | string | Headings. Default: the text colour. |
theme.accent_color | string | Table header rules, callout tint, and the cover when it has no background_color. |
theme.font_size | number | Body size in points. Default 11. |
theme.line_height | number | Default 1.45. |
theme.page_size | "A4" | "Letter" | Default A4. |
theme.margin | number | Page margin in points. Default 56. |
theme.page_numbers | boolean | Default true. Never on the cover. |
theme.header_logo | boolean | The business's logo at the top right of every page except the cover. |
blocks | array of object | A block document: squiggli lays it out on the page. Text can use {{variables}}. |
blocks[].type required | "heading" | |
blocks[].text required | string | |
blocks[].level | 1 or 2 or 3 | |
blocks[].color | string | |
blocks[].align | "left" | "center" | "right" | |
file_base64 | string | Or a PDF (base64) with fields placed on it. |
file_url | string | |
fields | array of object | Fields on the PDF, by role. Only with file_base64 or file_url. |
fields[].type required | "signature" | "initials" | "date_signed" | "name" | "email" | "text" | "checkbox" | |
fields[].page required | integer | 1 is the first page. |
fields[].x required | number | PDF points from the left edge of the page (A4 is 595 x 842 points). |
fields[].y required | number | PDF points from the top edge of the page. |
fields[].width | number | Points. Defaults by type: signature 200, initials 60, checkbox 14, others 160. |
fields[].height | number | Points. Defaults by type: signature 50, initials 32, checkbox 14, others 22. |
fields[].required | boolean | Default true, except checkboxes. |
fields[].label | string | |
fields[].key | string | Your own name for the field. Returned with its value in GET /v1/envelopes/{id}. |
fields[].role required | string | Signer role, e.g. "tenant" or "landlord". |
roles | array of object | Labels for the roles the fields use. Worked out from the fields when left out. |
roles[].key required | string | Signer role, e.g. "tenant" or "landlord". |
roles[].label | string |
squiggli_preview_template
Preview a template.
| Input | Type | Description |
|---|---|---|
template_id required | string | The template (tpl_...) id |
variables | object | Sample values for {{variables}}. Missing ones show as {{name}}. |
squiggli_upload_image
Upload an image.
| Input | Type | Description |
|---|---|---|
name | string | |
file_base64 | string | PNG or JPEG, base64, up to 4 MB. |
file_url | string |
squiggli_update_template
Update template.
| Input | Type | Description |
|---|---|---|
name | string | Required unless you use a starter (its name is the default). |
description | string | |
starter | string | Start from a ready-made design (GET /v1/templates/starters), e.g. "statement-of-work". Anything else you send overrides it. |
theme | object | How the document looks. Every setting is optional. |
theme.font | "helvetica" | "inter" | "roboto" | "poppins" | "montserrat" | "open-sans" | "lora" | "merriweather" | "playfair-display" | "instrument-sans" | "familjen-grotesk" | Body font. Default helvetica. |
theme.heading_font | "helvetica" | "inter" | "roboto" | "poppins" | "montserrat" | "open-sans" | "lora" | "merriweather" | "playfair-display" | "instrument-sans" | "familjen-grotesk" | Heading and cover title font. Default: the body font. |
theme.text_color | string | Body text. Default #141a2e. |
theme.heading_color | string | Headings. Default: the text colour. |
theme.accent_color | string | Table header rules, callout tint, and the cover when it has no background_color. |
theme.font_size | number | Body size in points. Default 11. |
theme.line_height | number | Default 1.45. |
theme.page_size | "A4" | "Letter" | Default A4. |
theme.margin | number | Page margin in points. Default 56. |
theme.page_numbers | boolean | Default true. Never on the cover. |
theme.header_logo | boolean | The business's logo at the top right of every page except the cover. |
blocks | array of object | A block document: squiggli lays it out on the page. Text can use {{variables}}. |
blocks[].type required | "heading" | |
blocks[].text required | string | |
blocks[].level | 1 or 2 or 3 | |
blocks[].color | string | |
blocks[].align | "left" | "center" | "right" | |
file_base64 | string | Or a PDF (base64) with fields placed on it. |
file_url | string | |
fields | array of object | Fields on the PDF, by role. Only with file_base64 or file_url. |
fields[].type required | "signature" | "initials" | "date_signed" | "name" | "email" | "text" | "checkbox" | |
fields[].page required | integer | 1 is the first page. |
fields[].x required | number | PDF points from the left edge of the page (A4 is 595 x 842 points). |
fields[].y required | number | PDF points from the top edge of the page. |
fields[].width | number | Points. Defaults by type: signature 200, initials 60, checkbox 14, others 160. |
fields[].height | number | Points. Defaults by type: signature 50, initials 32, checkbox 14, others 22. |
fields[].required | boolean | Default true, except checkboxes. |
fields[].label | string | |
fields[].key | string | Your own name for the field. Returned with its value in GET /v1/envelopes/{id}. |
fields[].role required | string | Signer role, e.g. "tenant" or "landlord". |
roles | array of object | Labels for the roles the fields use. Worked out from the fields when left out. |
roles[].key required | string | Signer role, e.g. "tenant" or "landlord". |
roles[].label | string | |
template_id required | string |
squiggli_create_webhook
Create webhook.
| Input | Type | Description |
|---|---|---|
url required | string | Public https URL that accepts POSTed JSON. |
events | array of "envelope.sent" | "envelope.viewed" | "envelope.signed" | "envelope.completed" | "envelope.declined" | "envelope.voided" | "envelope.expired" | Default: every event. |
all_envelopes | boolean | true: every envelope in the business. false (default): only envelopes made with this credential. |
squiggli_list_webhooks
List webhooks.
No inputs.
squiggli_create_api_key
Create API key.
| Input | Type | Description |
|---|---|---|
name required | string | |
mode | "live" | "test" |
squiggli_create_embed_token
Create embed token.
| Input | Type | Description |
|---|---|---|
scope required | "editor" | "envelope" | editor: the template editor. envelope: one envelope (build, review and send it). |
template_id | string | editor: open this template. Leave out to start a new one. |
envelope_id | string | Required for scope envelope. |
ttl_seconds | integer | Default 3600. |
squiggli_get_account
Get account.
No inputs.
squiggli_get_usage
Get usage.
| Input | Type | Description |
|---|---|---|
month | string | YYYY-MM. Default this month. |
squiggli_get_integration_guide
Get the integration guide.
| Input | Type | Description |
|---|---|---|
stack | "node" | "nextjs" | "python" | "php" | "curl" | Default node. |