Skip to main content
Glama

Create a letter

create_letter

Create a printed letter order (8.5x11, mailed in a #10 envelope) and get a payment link. Either write it (content.body, up to ~3 pages, optional photo) or mail the user's own PDF (content.pdf_url, a public https link, up to 6 pages). Set certified to "certified" for USPS Certified Mail with tracking and proof of delivery, or "certified_return_receipt" to add the recipient's signature; use these when the user needs proof (tax notice replies, lease notices, disputes, demand letters). Or set express for USPS Priority Mail (not with certified). Prices: get_pricing. Mails only after the user pays.

Input Schema

NameRequiredDescriptionDefault
toNoRecipient's US mailing address (or use recipients for several people)
fromYesReturn address; printed on the mail piece
contentYesThe letter: body text (optionally with a photo) or your own PDF
expressNoSend by express (USPS Priority Mail, usually 2–3 days, with tracking) for an extra charge; see get_pricing. Not available with certified.
certifiedNoUSPS Certified Mail. "certified": tracking number and proof of mailing and delivery. "certified_return_receipt": adds the recipient's signature as proof of delivery, which landlords, courts and agencies often require. "none": regular First-Class. Prices: get_pricing.none
recipientsNoSend the same piece to several people: 2-25 US addresses, used INSTEAD of to. Each gets their own order and tracking; one payment covers all.
customer_emailNoWhere to send the receipt and status updates
idempotency_keyNoAny unique string; retrying with the same key returns the original order instead of creating a duplicate

Output Schema

NameRequiredDescriptionDefault
idYesOrder id, ord_…
batchNoPresent when the order was created with recipients: the whole group. The top-level fields describe the first recipient's order; use batch.price and batch.checkout_url for the total and payment.
priceYes
objectYes
ordersNoEvery order in the group, when created with recipients
statusYesawaiting_payment, paid, printing, mailed, cancelled or refunded
productYesProduct id, e.g. postcard_4x6 or letter_certified
discountYesFirst-order discount, already taken off price; null when none applies
trackingYesUSPS tracking, for Certified Mail once printed
certifiedYesnone, certified or certified_return_receipt
order_urlYesOrder status page
preview_urlYesExact print preview
checkout_urlYesWhere the user pays; null once paid or cancelled
product_nameYes
status_detailYesPlain-English status to show the user
preview_image_urlNoPNG picture of the piece (postcard front and back, or the letter's first page) to show the user

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedOutput schema / properties / preview_image_url
      Added value: +{
      +  "description": "PNG picture of the piece (postcard front and back, or the letter's first page) to show the user",
      +  "type": "string"
      +}
  2. Changed15 schema fields changed
    • changedInput schema / properties / certified / description
      Previous value: -"USPS Certified Mail. \"certified\" ($14.99): tracking number and proof of mailing and delivery. \"certified_return_receipt\" ($19.99): adds the recipient's signature as proof of delivery, which landlords, courts and agencies often require. \"none\" ($4.99): regular First-Class."New value: +"USPS Certified Mail. \"certified\": tracking number and proof of mailing and delivery. \"certified_return_receipt\": adds the recipient's signature as proof of delivery, which landlords, courts and agencies often require. \"none\": regular First-Class. Prices: get_pricing."
    • changedInput schema / properties / content / description
      Previous value: -"The letter text and font"New value: +"The letter: body text (optionally with a photo) or your own PDF"
    • changedInput schema / properties / content / properties / body / description
      Previous value: -"Full letter text. Plain text; blank lines separate paragraphs."New value: +"Full letter text. Plain text; blank lines separate paragraphs. Use this OR pdf_url."
    • addedInput schema / properties / content / properties / color
      Added value: +{
      +  "description": "PDF letters only: print in color (costs a little more; see get_pricing). Text letters print in color automatically when they include image_url.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / content / properties / font / description
      Previous value: -"Typeface for the letter body"New value: +"Typeface for the letter body (text letters)"
    • changedInput schema / properties / content / properties / image_url / description
      Previous value: -"Optional photo printed at the top of the letter (https JPG or PNG). A letter with a photo prints in color, for a small surcharge (see get_pricing)."New value: +"Text letters only: optional photo printed at the top (https JPG or PNG). A letter with a photo prints in color, for a small surcharge (see get_pricing)."
    • addedInput schema / properties / content / properties / pdf_pages
      Added value: +{
      +  "description": "Set by Sendpaper: page count of the PDF",
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedInput schema / properties / content / properties / pdf_url
      Added value: +{
      +  "description": "Mail your own document instead of body text: a public https link to a PDF (up to 6 pages). Pages are fitted to 8.5×11 and a blank address page is added in front.",
      +  "maxLength": 2000,
      +  "type": "string"
      +}
    • removedInput schema / properties / content / required
      Removed value: -[
      -  "body"
      -]
    • addedInput schema / properties / express
      Added value: +{
      +  "default": false,
      +  "description": "Send by express (USPS Priority Mail, usually 2–3 days, with tracking) for an extra charge; see get_pricing. Not available with certified.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / recipients
      Added value: +{
      +  "description": "Send the same piece to several people: 2-25 US addresses, used INSTEAD of to. Each gets their own order and tracking; one payment covers all.",
      +  "items": {
      +    "properties": {
      +      "city": {
      +        "description": "City",
      +        "maxLength": 40,
      +        "minLength": 2,
      +        "type": "string"
      +      },
      +      "company": {
      +        "description": "Company name, printed under the person's name",
      +        "maxLength": 60,
      +        "type": "string"
      +      },
      +      "line1": {
      +        "description": "Street address",
      +        "maxLength": 64,
      +        "minLength": 3,
      +        "type": "string"
      +      },
      +      "line2": {
      +        "description": "Apartment, suite, unit",
      +        "maxLength": 64,
      +        "type": "string"
      +      },
      +      "name": {
      +        "description": "Recipient or sender full name",
      +        "maxLength": 60,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "state": {
      +        "description": "Two-letter US state code, e.g. NY",
      +        "type": "string"
      +      },
      +      "zip": {
      +        "description": "5-digit US ZIP code, or ZIP+4",
      +        "pattern": "^\\d{5}(-\\d{4})?$",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "line1",
      +      "city",
      +      "state",
      +      "zip"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 25,
      +  "minItems": 2,
      +  "type": "array"
      +}
    • changedInput schema / properties / to / description
      Previous value: -"Recipient's US mailing address"New value: +"Recipient's US mailing address (or use recipients for several people)"
    • changedInput schema / required
      Previous value: -[
      -  "to",
      -  "from",
      -  "content"
      -]New value: +[
      +  "from",
      +  "content"
      +]
    • addedOutput schema / properties / batch
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Present when the order was created with recipients: the whole group. The top-level fields describe the first recipient's order; use batch.price and batch.checkout_url for the total and payment.",
      +  "properties": {
      +    "checkout_url": {
      +      "description": "One payment link for every unpaid order in the group",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "count": {
      +      "description": "How many recipients (one order each)",
      +      "type": "number"
      +    },
      +    "discount": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "amount_cents": {
      +              "type": "number"
      +            },
      +            "display": {
      +              "type": "string"
      +            },
      +            "reason": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "amount_cents",
      +            "display",
      +            "reason"
      +          ],
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "id": {
      +      "type": "string"
      +    },
      +    "price": {
      +      "additionalProperties": false,
      +      "description": "Total for the whole group",
      +      "properties": {
      +        "amount_cents": {
      +          "type": "number"
      +        },
      +        "currency": {
      +          "type": "string"
      +        },
      +        "display": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "amount_cents",
      +        "currency",
      +        "display"
      +      ],
      +      "type": "object"
      +    },
      +    "url": {
      +      "description": "Group page listing every recipient",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "count",
      +    "url",
      +    "checkout_url",
      +    "price",
      +    "discount"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / orders
      Added value: +{
      +  "description": "Every order in the group, when created with recipients",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": "string"
      +      },
      +      "order_url": {
      +        "type": "string"
      +      },
      +      "preview_url": {
      +        "type": "string"
      +      },
      +      "to": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id",
      +      "to",
      +      "order_url",
      +      "preview_url"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  3. Changed4 schema fields changed
    • addedInput schema / properties / content / properties / image_url
      Added value: +{
      +  "description": "Optional photo printed at the top of the letter (https JPG or PNG). A letter with a photo prints in color, for a small surcharge (see get_pricing).",
      +  "maxLength": 2000,
      +  "type": "string"
      +}
    • addedOutput schema / properties / discount
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "amount_cents": {
      +          "type": "number"
      +        },
      +        "display": {
      +          "type": "string"
      +        },
      +        "reason": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "amount_cents",
      +        "display",
      +        "reason"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "First-order discount, already taken off price; null when none applies"
      +}
    • removedOutput schema / properties / first_postcard_free
      Removed value: -{
      -  "additionalProperties": false,
      -  "description": "Present when the first-postcard-free offer applies",
      -  "properties": {
      -    "applied": {
      -      "type": "boolean"
      -    },
      -    "eligible": {
      -      "type": "boolean"
      -    },
      -    "how": {
      -      "type": "string"
      -    }
      -  },
      -  "type": "object"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "id",
      -  "object",
      -  "product",
      -  "product_name",
      -  "certified",
      -  "status",
      -  "status_detail",
      -  "price",
      -  "checkout_url",
      -  "order_url",
      -  "preview_url",
      -  "tracking"
      -]New value: +[
      +  "id",
      +  "object",
      +  "product",
      +  "product_name",
      +  "certified",
      +  "status",
      +  "status_detail",
      +  "price",
      +  "checkout_url",
      +  "order_url",
      +  "preview_url",
      +  "tracking",
      +  "discount"
      +]
  4. Changed13 schema fields changed
    • addedInput schema / properties / content / description
      Added value: +"The letter text and font"
    • addedInput schema / properties / content / properties / font / description
      Added value: +"Typeface for the letter body"
    • addedInput schema / properties / from / properties / city / description
      Added value: +"City"
    • addedInput schema / properties / from / properties / company / description
      Added value: +"Company name, printed under the person's name"
    • addedInput schema / properties / from / properties / state / description
      Added value: +"Two-letter US state code, e.g. NY"
    • addedInput schema / properties / from / properties / zip / description
      Added value: +"5-digit US ZIP code, or ZIP+4"
    • addedInput schema / properties / idempotency_key / description
      Added value: +"Any unique string; retrying with the same key returns the original order instead of creating a duplicate"
    • addedInput schema / properties / to / description
      Added value: +"Recipient's US mailing address"
    • addedInput schema / properties / to / properties / city / description
      Added value: +"City"
    • addedInput schema / properties / to / properties / company / description
      Added value: +"Company name, printed under the person's name"
    • addedInput schema / properties / to / properties / state / description
      Added value: +"Two-letter US state code, e.g. NY"
    • addedInput schema / properties / to / properties / zip / description
      Added value: +"5-digit US ZIP code, or ZIP+4"
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": {},
      +  "properties": {
      +    "certified": {
      +      "description": "none, certified or certified_return_receipt",
      +      "type": "string"
      +    },
      +    "checkout_url": {
      +      "description": "Where the user pays; null once paid or cancelled",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "first_postcard_free": {
      +      "additionalProperties": false,
      +      "description": "Present when the first-postcard-free offer applies",
      +      "properties": {
      +        "applied": {
      +          "type": "boolean"
      +        },
      +        "eligible": {
      +          "type": "boolean"
      +        },
      +        "how": {
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "id": {
      +      "description": "Order id, ord_…",
      +      "type": "string"
      +    },
      +    "object": {
      +      "enum": [
      +        "postcard",
      +        "letter"
      +      ],
      +      "type": "string"
      +    },
      +    "order_url": {
      +      "description": "Order status page",
      +      "type": "string"
      +    },
      +    "preview_url": {
      +      "description": "Exact print preview",
      +      "type": "string"
      +    },
      +    "price": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "amount_cents": {
      +          "type": "number"
      +        },
      +        "currency": {
      +          "type": "string"
      +        },
      +        "display": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "amount_cents",
      +        "currency",
      +        "display"
      +      ],
      +      "type": "object"
      +    },
      +    "product": {
      +      "description": "Product id, e.g. postcard_4x6 or letter_certified",
      +      "type": "string"
      +    },
      +    "product_name": {
      +      "type": "string"
      +    },
      +    "status": {
      +      "description": "awaiting_payment, paid, printing, mailed, cancelled or refunded",
      +      "type": "string"
      +    },
      +    "status_detail": {
      +      "description": "Plain-English status to show the user",
      +      "type": "string"
      +    },
      +    "tracking": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "number": {
      +              "type": "string"
      +            },
      +            "url": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "number",
      +            "url"
      +          ],
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "USPS tracking, for Certified Mail once printed"
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "object",
      +    "product",
      +    "product_name",
      +    "certified",
      +    "status",
      +    "status_detail",
      +    "price",
      +    "checkout_url",
      +    "order_url",
      +    "preview_url",
      +    "tracking"
      +  ],
      +  "type": "object"
      +}
  5. Changed1 schema field changed
    • addedInput schema / properties / certified
      Added value: +{
      +  "default": "none",
      +  "description": "USPS Certified Mail. \"certified\" ($14.99): tracking number and proof of mailing and delivery. \"certified_return_receipt\" ($19.99): adds the recipient's signature as proof of delivery, which landlords, courts and agencies often require. \"none\" ($4.99): regular First-Class.",
      +  "enum": [
      +    "none",
      +    "certified",
      +    "certified_return_receipt"
      +  ],
      +  "type": "string"
      +}
  6. First observed

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare it is a write operation (readOnlyHint=false) that is non-destructive and open-world; the description adds the crucial behavioral fact that nothing mails until the user pays, plus the payment-link flow. It does not describe rate limits or cancellation, but a sibling cancel_order exists so that is inferable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what the tool produces, then the content choice, then the mailing options. Dense but every sentence carries a decision-relevant constraint; only slight compression cost from packing pricing and enum guidance together.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter, multi-mode, payment-gated tool with an output schema, the description covers the key decision paths (body vs PDF, certified levels, express) and the pay-before-mail rule. It omits the multi-recipient 'recipients' path, which the schema documents but the description never mentions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real decision semantics: body vs pdf_url mutually exclusive alternatives with page limits, certified enum value meanings, and the express/certified incompatibility. This meaningfully exceeds the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Create a printed letter order') and immediately scopes it (8.5x11, #10 envelope, returns a payment link). It is clearly distinguishable from the sibling create_postcard by naming the letter format and envelope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use guidance for certified vs certified_return_receipt (tax notice replies, lease notices, disputes) and notes express is 'not with certified'. It does not explicitly contrast against create_postcard, but the routing to get_pricing and the payment-gated flow are clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.