---
title: "Dry-run validation + pricing for an order"
method: POST
path: "/api/v1/validate"
---

# Dry-run validation + pricing for an order

`POST /api/v1/validate`

## Request

- Base URL: `https://www.premierletters.com`
- URL: `https://www.premierletters.com/api/v1/validate`
- Auth: HTTP bearer

## Request body

- OrderCreate
  - `message` string, required: Letter body. Supports {{first_name}}/{{last_name}}/{{greeting}} merge fields.
  - `recipients` Recipient[]
    - `first_name` string
    - `last_name` string
    - `address_line1` string
    - `address_line2` string
    - `city` string
    - `state` string: Two-letter US state code
    - `zip` string
    - `custom_fields` object
  - `options` OrderOptions
    - `handwriting_style` string: Font UUID from GET /api/v1/styles
    - `paper_type` 'standard' | 'premium'
    - `product_type` string: e.g. letter, card, postcard
    - `authenticity_preset` string
    - `mailing_option` 'we_mail' | 'you_mail_stamped' | 'you_mail_no_stamp': Delivery option. Omit to use the account's default mailing option (else we_mail).
    - `include_letter` boolean
    - `include_envelope` boolean
    - `copies` integer: Values above 1 only for ship-to-you mailing options
    - `output_mode` 'handwritten' | 'printed_bw' | 'printed_color': How the letter body is produced: pen-written (default) or printed in black & white / color.
    - `envelope_output_mode` 'printed_bw' | 'printed_color' | 'null', nullable: How the envelope is produced: null (default) = hand-addressed, or printed. Independent of output_mode.
  - `payment` object
    - `method` 'card_on_file' | 'checkout_session' | 'balance': balance pays from the prepaid balance and waives the small-order handling fee (orders under 5 pieces); 402 insufficient_balance when short.
    - `return_url` string, uri
  - `skip_invalid` boolean
  - `return_address` ReturnAddress: Return address written on the envelope. Omit to use the account default (Settings). Required for an envelope order unless the account has a default or no_return_address_ack is true. name, address_line1, city, state and zip are required unless return_address_partial_ok is true (then at least one of name, company, address_line1, city, state, zip, printed as written).
    - `name` string
    - `company` string
    - `address_line1` string
    - `address_line2` string
    - `city` string
    - `state` string: Two-letter US state code
    - `zip` string: 5-digit ZIP or ZIP+4
  - `return_address_partial_ok` boolean: Send return_address exactly as written although it is incomplete: at least one of name, company, address_line1, city, state, zip. Only the filled lines print (a name alone is fine). Without it an incomplete return_address is refused.
  - `no_return_address_ack` boolean: Send with no return address at all. Only honoured when no return_address is given and the account has no default; undeliverable mail is then destroyed. Without it, such an order is a 400 no_return_address_unacknowledged.
  - `idempotency_key` string: Client-supplied key, 1-255 characters. A repeat with the same key and the same body returns the original order (200, idempotent_replay: true) instead of creating a second one. The same key with a different body is a 422 idempotency_key_reused; a repeat while the first request is still running is a 409 idempotency_in_progress. Also accepted as the Idempotency-Key header; the body wins.

## Response `200`

Order is valid; includes total_cents and a full PricingBreakdown

- object
  - `valid` boolean
  - `total_cents` integer
  - `breakdown` PricingBreakdown
    - `basePrice` integer: Cents
    - `paperSurchargeCents` integer
    - `printedPageSurchargeCents` integer
    - `printedEnvelopeSurchargeCents` integer
    - `signatureSurchargeCents` integer
    - `meterSurchargeCents` integer
    - `postageCents` integer: Postage passed through at face value; 0 when the customer stamps it themselves
    - `pieceCentsPerLetter` integer: Pen work per piece, excluding postage
    - `totalCents` integer
    - `perLetterCents` integer
    - `pieceCount` integer

## Other responses

- `400`: no_return_address_unacknowledged and other request errors
- `422`: One or more recipients/fields failed validation

## Changes

- **2026-10-20** `9dc302324ca1`: 6 info
  - added the new optional request property `return_address_partial_ok`
  - the request property `return_address/address_line1` became optional
  - the request property `return_address/city` became optional
  - the request property `return_address/name` became optional
  - …2 more

[Operation history](https://skmtc.dev/premierletters/apis/premier-letters-api/changes/api/v1/validate/post.md)

---

[API](https://skmtc.dev/premierletters/apis/premier-letters-api.md) · [All operations](https://skmtc.dev/premierletters/apis/premier-letters-api/llms.txt) · [OpenAPI document](https://skmtc.dev/premierletters/apis/premier-letters-api/revisions/9dc302324ca1?raw)
