{ "openapi": "3.1.0", "info": { "title": "PostalForm Projects Public API", "version": "2026-05-06", "description": "Public PostalForm Projects API for customer SDKs. Includes document uploads, quotes, mail orders, credits, API keys, and signed customer webhooks." }, "servers": [ { "url": "https://projects.postalform.com" } ], "paths": { "/api/v1/documents/upload-intent": { "post": { "summary": "Create a PDF upload intent.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "content_type": { "type": "string", "const": "application/pdf" }, "byte_size": { "type": "integer", "minimum": 1, "maximum": 26214400, "description": "PDF size in bytes. Projects currently limits uploads to 25 MiB while preparation runs inside the Worker memory budget." }, "page_count": { "type": "integer", "minimum": 1, "description": "Optional known PDF page count. Used for quote validation and pricing if supplied." } }, "required": [ "content_type", "byte_size" ] } } } }, "responses": { "200": { "description": "Upload instructions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UploadIntent" } } } } }, "operationId": "createUploadIntent" } }, "/api/v1/documents/{document_id}/complete": { "post": { "summary": "Mark an uploaded document complete after the object is present.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/DocumentId" } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "page_count": { "type": "integer", "minimum": 1, "description": "Optional PDF page count if it was not supplied during upload-intent creation." } } } } } }, "responses": { "200": { "description": "Validated document.", "content": { "application/json": { "schema": { "type": "object", "properties": { "document_id": { "type": "string" }, "status": { "type": "string", "enum": [ "validated" ] } } } } } } }, "operationId": "completeDocumentUpload" } }, "/api/v1/letters/quotes": { "post": { "summary": "Quote a mailpiece.", "description": "Quote a letter from document size, country codes, mail class, and proof-mail settings. Country codes default to US when omitted. PostalForm automatically selects an eligible fulfillment path; API clients choose mailpiece options, not the underlying production network.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateQuoteRequest" } } } }, "responses": { "200": { "description": "Quote.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Quote" } } } } }, "operationId": "createLetterQuote" } }, "/api/v1/letters": { "post": { "summary": "Create a test or live mail order from a quote.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateLetterRequest" } } } }, "responses": { "200": { "description": "Idempotent replay.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Letter" } } } }, "201": { "description": "Created order.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Letter" } } } } }, "operationId": "createLetter" } }, "/api/v1/letters/{order_id}": { "get": { "summary": "Retrieve a mail order, timeline, tracking fields, and customer webhook events.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/OrderId" } ], "responses": { "200": { "description": "Order detail.", "content": { "application/json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/Letter" }, { "type": "object", "properties": { "timeline": { "type": "array", "items": { "$ref": "#/components/schemas/MailOrderEvent" } }, "webhook_events": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEvent" } } } } ] } } } } }, "operationId": "getLetter" } }, "/api/v1/letters/{order_id}/document.pdf": { "get": { "summary": "Preview or download the PDF for a letter order.", "description": "Streams the prepared PDF when available, otherwise the original uploaded PDF while preparation is pending. Documents follow the workspace document retention window.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/OrderId" }, { "name": "version", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "current", "original", "prepared" ], "default": "current" }, "description": "current returns the prepared PDF when available and otherwise the original upload." }, { "name": "disposition", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "inline", "attachment" ], "default": "inline" }, "description": "Use attachment to download instead of previewing inline." } ], "responses": { "200": { "description": "PDF bytes.", "content": { "application/pdf": { "schema": { "type": "string", "format": "binary" } } } } }, "operationId": "getLetterDocument" } }, "/api/v1/letters/{order_id}/return-receipt.pdf": { "get": { "summary": "Download a stored USPS electronic return receipt.", "description": "Returns the signed USPS proof-of-delivery PDF after it has been acquired for an order using automatic ERR delivery. The PDF contains USPS delivery details and the recipient signature image or approved hand-stamp supplied by USPS. The order response exposes availability and the retention deadline.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/OrderId" } ], "responses": { "200": { "description": "USPS electronic return receipt PDF.", "content": { "application/pdf": { "schema": { "type": "string", "format": "binary" } } } }, "404": { "description": "The receipt has not been acquired or is not available for this order." }, "410": { "description": "The stored receipt has passed its retention deadline." } }, "operationId": "getLetterReturnReceipt" } }, "/api/v1/return-receipts/export.zip": { "get": { "summary": "Export stored electronic return receipts in bulk.", "description": "Downloads up to 500 available receipt PDFs plus a CSV manifest in one ZIP archive. Use the optional date range to partition larger exports.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "created_after", "in": "query", "required": false, "schema": { "type": "string", "format": "date-time" }, "description": "Include orders created at or after this ISO 8601 date-time." }, { "name": "created_before", "in": "query", "required": false, "schema": { "type": "string", "format": "date-time" }, "description": "Include orders created before this ISO 8601 date-time." } ], "responses": { "200": { "description": "ZIP archive containing manifest.csv and the available receipt PDFs.", "content": { "application/zip": { "schema": { "type": "string", "format": "binary" } } } }, "400": { "description": "Invalid date range." }, "413": { "description": "Export exceeds the 500-receipt or 25 MiB limit; narrow the date range." } }, "operationId": "exportReturnReceipts" } }, "/api/v1/postcards/quotes": { "post": { "summary": "Quote a postcard mailpiece.", "description": "Postcards require a fully composed two-page PDF and a postcard_size of 4x6, 6x9, or 11x6. Postcards are first-class, color, double-sided mailpieces and do not support certified or registered mail.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatePostcardQuoteRequest" } } } }, "responses": { "200": { "description": "Postcard quote.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Quote" } } } } }, "operationId": "createPostcardQuote" } }, "/api/v1/postcards": { "post": { "summary": "Create a test or live postcard order from a postcard quote.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateLetterRequest" } } } }, "responses": { "200": { "description": "Idempotent replay.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Letter" } } } }, "201": { "description": "Created postcard order.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Letter" } } } } }, "operationId": "createPostcard" } }, "/api/v1/postcards/{order_id}": { "get": { "summary": "Retrieve a postcard order, timeline, tracking fields, and customer webhook events.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/OrderId" } ], "responses": { "200": { "description": "Postcard order detail.", "content": { "application/json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/Letter" }, { "type": "object", "properties": { "timeline": { "type": "array", "items": { "$ref": "#/components/schemas/MailOrderEvent" } }, "webhook_events": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEvent" } } } } ] } } } } }, "operationId": "getPostcard" } }, "/api/v1/postcards/{order_id}/document.pdf": { "get": { "summary": "Preview or download the PDF for a postcard order.", "description": "Streams the prepared postcard PDF when available, otherwise the original uploaded PDF while preparation is pending. Documents follow the workspace document retention window.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/OrderId" }, { "name": "version", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "current", "original", "prepared" ], "default": "current" }, "description": "current returns the prepared PDF when available and otherwise the original upload." }, { "name": "disposition", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "inline", "attachment" ], "default": "inline" }, "description": "Use attachment to download instead of previewing inline." } ], "responses": { "200": { "description": "PDF bytes.", "content": { "application/pdf": { "schema": { "type": "string", "format": "binary" } } } } }, "operationId": "getPostcardDocument" } }, "/api/v1/webhook-endpoints": { "get": { "summary": "List customer webhook endpoints for the workspace.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Endpoints.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEndpoint" } } } } } } } }, "operationId": "listWebhookEndpoints" }, "post": { "summary": "Configure a customer webhook endpoint for status events.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "url": { "type": "string", "format": "uri", "pattern": "^https://", "description": "HTTPS endpoint that receives signed PostalForm status webhooks." }, "signing_secret": { "type": "string", "description": "Optional. Generated if omitted." } }, "required": [ "url" ] } } } }, "responses": { "200": { "description": "Created endpoint.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookEndpointSecretResponse" } } } } }, "operationId": "createWebhookEndpoint" } }, "/api/v1/webhook-endpoints/{endpoint_id}": { "delete": { "summary": "Disable a customer webhook endpoint.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "endpoint_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Disabled endpoint.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookEndpoint" } } } } }, "operationId": "disableWebhookEndpoint" } }, "/api/v1/webhook-endpoints/{endpoint_id}/rotate-secret": { "post": { "summary": "Rotate a customer webhook endpoint signing secret.", "description": "Returns the new signing secret once. Store it securely; list endpoints does not expose secrets.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "endpoint_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Rotated endpoint signing secret.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookEndpointSecretResponse" } } } } }, "operationId": "rotateWebhookEndpointSecret" } }, "/api/v1/webhook-events": { "get": { "summary": "List customer webhook events for the workspace.", "description": "Customer webhook events are fulfillment status-change events only. Event names use `postalform.{letter|postcard}.{status}` and are emitted for `accepted`, `in_transit`, `delivered`, `returned`, `failed`, and `canceled`.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Events.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEvent" } } } } } } } }, "operationId": "listWebhookEvents" } }, "/api/v1/webhook-events/{event_id}/replay": { "post": { "summary": "Queue a customer webhook event for replay.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "$ref": "#/components/parameters/EventId" } ], "responses": { "200": { "description": "Replay queued." } }, "operationId": "replayWebhookEvent" } }, "/api/v1/credits/balance": { "get": { "summary": "Get prepaid credit balance.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Balance.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreditBalance" } } } } }, "operationId": "getCreditBalance" } }, "/api/v1/credits/payment-methods": { "get": { "summary": "List saved live billing payment methods.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Saved payment methods for live auto-refill.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/BillingPaymentMethod" } } } } } } } }, "operationId": "listPaymentMethods" } }, "/api/v1/credits/payment-methods/setup-session": { "post": { "summary": "Create a Checkout setup session for live credit auto-refill.", "description": "Requires a live API key. The returned Checkout URL lets the customer save a payment method for future off-session auto-refill charges.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Checkout setup session URL.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentMethodSetupSession" } } } } }, "operationId": "createPaymentMethodSetupSession" } }, "/api/v1/credits/auto-refill": { "get": { "summary": "Get credit auto-refill threshold policies.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Auto-refill policies for test and live credit balances.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreditAutoRefillPolicies" } } } } }, "operationId": "getCreditAutoRefillPolicies" }, "post": { "summary": "Configure the credit auto-refill threshold for the authenticated key mode.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreditAutoRefillRequest" } } } }, "responses": { "200": { "description": "Updated auto-refill policy.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CreditAutoRefillPolicy" } } } } } } }, "operationId": "configureCreditAutoRefill" } }, "/api/v1/credits/ledger": { "get": { "summary": "List prepaid credit ledger entries.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Ledger entries.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/CreditLedgerEntry" } } } } } } } }, "operationId": "listCreditLedger" } }, "/api/v1/api-keys": { "get": { "summary": "List API key prefixes and status.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "API keys.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ApiKey" } } } } } } } }, "operationId": "listApiKeys" } }, "/api/v1/api-keys/rotate": { "post": { "summary": "Rotate a test or live API key.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "mode": { "$ref": "#/components/schemas/Mode" } }, "required": [ "mode" ] } } } }, "responses": { "200": { "description": "New API key secret. Returned once.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyRotation" } } } } }, "operationId": "rotateApiKey" } }, "/api/v1/credits/checkout-session": { "post": { "summary": "Create a prepaid credit top-up checkout session.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "amount_cents": { "type": "integer", "minimum": 1 } } } } } }, "responses": { "200": { "description": "Stripe Checkout URL in configured environments, or a local checkout stub URL for local development.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreditCheckoutSession" } } } } }, "operationId": "createCreditCheckoutSession" } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" } }, "schemas": { "UploadIntent": { "type": "object", "properties": { "document_id": { "type": "string" }, "upload_url": { "type": "string", "format": "uri" }, "upload_method": { "type": "string", "enum": [ "PUT" ] }, "expires_at": { "type": "string", "format": "date-time" } } }, "CreateQuoteRequest": { "type": "object", "description": "Letter quote request. API clients choose mailpiece options; PostalForm handles fulfillment automatically.", "properties": { "document_id": { "type": "string" }, "page_count": { "type": "integer", "minimum": 1, "description": "Optional explicit PDF page count. Used for deterministic pricing when present." }, "mail_class": { "type": "string", "default": "usps_first_class", "description": "Standard/USPS First Class by default. Accepts standard/usps_first_class, priority/usps_priority, and express/usps_express. Priority/Express cannot be combined with certified or registered proof mail." }, "color": { "type": "boolean", "default": false }, "double_sided": { "type": "boolean", "default": true }, "standalone_address_page": { "type": "boolean", "description": "Keep the address page on its own sheet with a blank reverse for double-sided letters, preserving the document page pairing. Omit to inherit the workspace setting (off by default); explicit true or false overrides it. Single-sided letters are unchanged. The resolved choice is fixed on the quote, and added pages or sheets are included in pricing and provider limits." }, "certified": { "type": "boolean", "default": false, "description": "Proof-mail add-on for letters only. Eligible U.S. standard letters request USPS Certified Mail. Eligible Canada standard letters request Canada Post Registered Mail. Eligible Belgium, Switzerland, Spain, and France standard letters request the available registered-mail option for that destination." }, "certified_return_receipt": { "type": "boolean", "default": false, "description": "Return receipt for eligible U.S. Certified Mail letters. Defaults to the electronic format when true." }, "return_receipt_format": { "type": "string", "enum": [ "electronic", "physical" ], "default": "electronic", "description": "Electronic selects the USPS signed proof-of-delivery PDF. Physical selects the mailed PS Form 3811 green card. Requires certified_return_receipt=true." }, "restricted_delivery": { "type": "boolean", "default": false, "description": "Requests USPS Restricted Delivery for addressee-only delivery. Requires certified_return_receipt=true and uses the provider-managed restricted-delivery service." }, "err_delivery": { "type": "string", "enum": [ "manual", "email" ], "default": "manual", "description": "Manual leaves receipt retrieval to the customer through the USPS tracking link. Email makes PostalForm acquire, retain, and email the electronic receipt when available." }, "err_email": { "type": "string", "format": "email", "maxLength": 256, "description": "Optional destination when err_delivery=email. If omitted, PostalForm uses the Projects account email. Not valid for a physical PS Form 3811." }, "signature_required": { "type": "boolean", "default": false, "description": "Signature confirmation for eligible U.S. Priority and Express letters." }, "destination_country_code": { "type": "string", "minLength": 2, "maxLength": 2, "default": "US", "description": "ISO 3166-1 alpha-2 destination country code used for quote validation and pricing. Defaults to US. First-party Projects destinations are US, CA, AT, BE, CH, DE, ES, FR, GB, IN, LU, and NL." }, "origin_country_code": { "type": "string", "minLength": 2, "maxLength": 2, "default": "US", "description": "ISO 3166-1 alpha-2 sender/origin country code used for quote validation and pricing. Defaults to US." } }, "required": [ "document_id" ] }, "Quote": { "type": "object", "properties": { "standalone_address_page": { "type": "boolean", "description": "Resolved standalone address page setting saved on this quote. Always false for postcards." }, "quote_id": { "type": "string" }, "mailpiece_type": { "type": "string", "enum": [ "letter", "postcard" ] }, "postcard_size": { "type": [ "string", "null" ], "enum": [ "4x6", "6x9", "11x6", null ] }, "price_cents": { "type": "integer" }, "currency": { "type": "string", "enum": [ "usd" ] }, "pricing_version": { "type": "string" }, "certified_return_receipt": { "type": "boolean" }, "return_receipt_format": { "type": "string", "enum": [ "electronic", "physical" ] }, "restricted_delivery": { "type": "boolean" }, "err_delivery": { "type": "string", "enum": [ "manual", "email" ] }, "err_email": { "type": [ "string", "null" ], "format": "email" }, "signature_required": { "type": "boolean" }, "expires_at": { "type": "string", "format": "date-time" } } }, "CreateLetterRequest": { "type": "object", "description": "Create an order from a quote. Requires Idempotency-Key header. Sender is strongly recommended for all live mail and required for some destinations and mailpiece options.", "properties": { "quote_id": { "type": "string" }, "recipient": { "$ref": "#/components/schemas/MailingAddress" }, "sender": { "$ref": "#/components/schemas/MailingAddress" }, "metadata": { "type": "object", "description": "Optional caller metadata stored on the order and surfaced in reads/webhook payloads.", "additionalProperties": true } }, "required": [ "quote_id", "recipient" ] }, "Letter": { "type": "object", "properties": { "id": { "type": "string" }, "object": { "type": "string", "enum": [ "letter", "postcard" ] }, "mailpiece_type": { "type": "string", "enum": [ "letter", "postcard" ] }, "postcard_size": { "type": [ "string", "null" ], "enum": [ "4x6", "6x9", "11x6", null ] }, "status": { "$ref": "#/components/schemas/MailOrderStatus" }, "mode": { "$ref": "#/components/schemas/Mode" }, "price_cents": { "type": "integer" }, "currency": { "type": "string" }, "funds_status": { "type": "string" }, "billing_rail": { "type": "string" }, "tracking_number": { "type": "string", "nullable": true, "description": "Carrier tracking number when available." }, "tracking_url": { "type": [ "string", "null" ], "format": "uri", "description": "Direct USPS tracking URL when a tracking number is available. Manual ERR customers can use it to request their receipt from USPS." }, "tracking_status": { "type": "string", "nullable": true, "description": "Normalized tracking status when available." }, "return_receipt_format": { "type": "string", "enum": [ "electronic", "physical" ] }, "restricted_delivery": { "type": "boolean" }, "err_delivery": { "type": "string", "enum": [ "manual", "email" ] }, "err_email": { "type": [ "string", "null" ], "format": "email" }, "err_status": { "type": "string", "enum": [ "manual", "pending", "sent", "failed", "expired" ] }, "err_delivered_at": { "type": [ "string", "null" ], "format": "date-time" }, "err_retention_until": { "type": [ "string", "null" ], "format": "date-time", "description": "Last instant at which an acquired receipt remains retrievable. PostalForm's default ERR retention is three years." }, "return_receipt_available": { "type": "boolean", "description": "Whether a stored electronic receipt can currently be downloaded." }, "return_receipt_url": { "type": [ "string", "null" ], "description": "Relative authenticated download URL when return_receipt_available is true." }, "metadata": { "type": "object", "additionalProperties": true }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "idempotent_replay": { "type": "boolean" } } }, "MailOrderEvent": { "type": "object", "description": "Customer-facing order timeline event. Internal fulfillment identifiers are not exposed.", "properties": { "id": { "type": "string" }, "event_type": { "type": "string" }, "status_before": { "type": "string" }, "status_after": { "type": "string" }, "source": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" } } }, "WebhookEvent": { "type": "object", "properties": { "id": { "type": "string" }, "workspaceId": { "type": "string" }, "orderId": { "type": "string" }, "eventType": { "$ref": "#/components/schemas/CustomerWebhookEventType" }, "payload": { "$ref": "#/components/schemas/CustomerWebhookPayload" }, "createdAt": { "type": "string", "format": "date-time" }, "deliveries": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookDeliveryAttempt" } } } }, "CreatePostcardQuoteRequest": { "type": "object", "description": "Postcard quote request. Postcards force first-class color double-sided mail and cannot use certified or registered mail.", "properties": { "document_id": { "type": "string" }, "page_count": { "type": "integer", "minimum": 1, "description": "Optional explicit PDF page count. Postcard source PDFs should be fully composed." }, "postcard_size": { "type": "string", "enum": [ "4x6", "6x9", "11x6" ] }, "destination_country_code": { "type": "string", "minLength": 2, "maxLength": 2, "default": "US", "description": "ISO 3166-1 alpha-2 destination country code used for quote validation and pricing. Defaults to US." }, "origin_country_code": { "type": "string", "minLength": 2, "maxLength": 2, "default": "US", "description": "ISO 3166-1 alpha-2 sender/origin country code used for quote validation and pricing. Defaults to US." } }, "required": [ "document_id", "postcard_size" ] }, "WebhookEndpoint": { "type": "object", "properties": { "id": { "type": "string" }, "url": { "type": "string", "format": "uri", "pattern": "^https://" }, "status": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" } } }, "WebhookEndpointSecretResponse": { "type": "object", "properties": { "id": { "type": "string" }, "url": { "type": "string", "format": "uri", "pattern": "^https://" }, "status": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "signing_secret": { "type": "string", "description": "Returned only when the endpoint is created or its signing secret is rotated." } } }, "CreditBalance": { "type": "object", "properties": { "mode": { "type": "string", "enum": [ "test", "live" ] }, "billing_rail": { "type": "string", "enum": [ "mock_test_credits", "prepaid_credits", "future_projects_spt", "future_metronome_streaming", "future_mpp_tempo", "manual_invoice" ] }, "available_cents": { "type": "integer" }, "reserved_cents": { "type": "integer" }, "currency": { "type": "string" }, "status": { "type": "string" }, "test": { "$ref": "#/components/schemas/CreditBalanceSnapshot" }, "live": { "$ref": "#/components/schemas/CreditBalanceSnapshot" }, "auto_refill": { "$ref": "#/components/schemas/CreditAutoRefillPolicies" } } }, "BillingPaymentMethod": { "type": "object", "properties": { "id": { "type": "string" }, "provider": { "type": "string", "enum": [ "stripe" ] }, "type": { "type": "string" }, "brand": { "type": "string" }, "last4": { "type": "string" }, "exp_month": { "type": "integer" }, "exp_year": { "type": "integer" }, "status": { "type": "string", "enum": [ "active", "disabled" ] }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "last_used_at": { "type": "string", "format": "date-time" } } }, "PaymentMethodSetupSession": { "type": "object", "properties": { "mode": { "type": "string", "enum": [ "stripe_checkout", "local_checkout_stub" ] }, "checkout_url": { "type": "string", "format": "uri" } } }, "CreditAutoRefillPolicies": { "type": "object", "properties": { "data": { "type": "object", "properties": { "test": { "anyOf": [ { "$ref": "#/components/schemas/CreditAutoRefillPolicy" }, { "type": "null" } ] }, "live": { "anyOf": [ { "$ref": "#/components/schemas/CreditAutoRefillPolicy" }, { "type": "null" } ] } } }, "test": { "anyOf": [ { "$ref": "#/components/schemas/CreditAutoRefillPolicy" }, { "type": "null" } ] }, "live": { "anyOf": [ { "$ref": "#/components/schemas/CreditAutoRefillPolicy" }, { "type": "null" } ] } } }, "CreditAutoRefillRequest": { "type": "object", "properties": { "mode": { "$ref": "#/components/schemas/Mode" }, "enabled": { "type": "boolean", "default": true }, "threshold_cents": { "type": "integer", "minimum": 100, "maximum": 100000 }, "refill_amount_cents": { "type": "integer", "minimum": 100, "maximum": 100000 } }, "required": [ "threshold_cents", "refill_amount_cents" ] }, "CreditAutoRefillPolicy": { "type": "object", "properties": { "id": { "type": "string" }, "workspace_id": { "type": "string" }, "mode": { "$ref": "#/components/schemas/Mode" }, "billing_rail": { "type": "string", "enum": [ "mock_test_credits", "prepaid_credits" ] }, "enabled": { "type": "boolean" }, "threshold_cents": { "type": "integer" }, "refill_amount_cents": { "type": "integer" }, "provider": { "type": "string", "enum": [ "test_grant", "stripe_checkout", "local_checkout_stub" ] }, "status": { "type": "string", "enum": [ "active", "disabled", "payment_action_required", "payment_pending", "payment_failed" ] }, "last_triggered_at": { "type": "string", "format": "date-time" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CreditLedgerEntry": { "type": "object", "properties": { "id": { "type": "string" }, "workspace_id": { "type": "string" }, "credit_account_id": { "type": "string" }, "order_id": { "type": "string" }, "mode": { "type": "string", "enum": [ "test", "live" ] }, "billing_rail": { "type": "string", "enum": [ "mock_test_credits", "prepaid_credits", "future_projects_spt", "future_metronome_streaming", "future_mpp_tempo", "manual_invoice" ] }, "type": { "type": "string", "enum": [ "test_grant", "topup", "reserve", "capture", "release", "refund", "adjustment" ] }, "amount_cents": { "type": "integer" }, "currency": { "type": "string" }, "external_reference": { "type": "string" }, "metadata": { "type": "object", "additionalProperties": true }, "created_at": { "type": "string", "format": "date-time" } } }, "ApiKey": { "type": "object", "properties": { "id": { "type": "string" }, "mode": { "$ref": "#/components/schemas/Mode" }, "prefix": { "type": "string" }, "status": { "type": "string", "enum": [ "active", "disabled", "revoked" ] }, "created_at": { "type": "string", "format": "date-time" }, "last_used_at": { "type": "string", "format": "date-time" } } }, "Mode": { "type": "string", "enum": [ "test", "live" ] }, "ApiKeyRotation": { "type": "object", "properties": { "mode": { "$ref": "#/components/schemas/Mode" }, "api_key": { "type": "string", "description": "Full API key secret. Returned once." }, "api_key_prefix": { "type": "string" } } }, "CreditCheckoutSession": { "type": "object", "properties": { "id": { "type": "string", "description": "PostalForm top-up ID." }, "mode": { "type": "string", "enum": [ "stripe_checkout", "local_checkout_stub" ] }, "checkout_url": { "type": "string", "format": "uri" }, "amount_cents": { "type": "integer" }, "currency": { "type": "string" } } }, "MailingAddress": { "type": "object", "description": "Flexible mailing address object. Pass countryCode, country_code, country, address_country, or addressCountry for international destinations; country defaults to US when omitted.", "additionalProperties": true, "properties": { "name": { "type": "string" }, "company": { "type": "string" }, "line1": { "type": "string", "description": "Also accepts street1, address_line1, or addressLine1." }, "line2": { "type": "string", "description": "Also accepts street2, address_line2, or addressLine2." }, "city": { "type": "string", "description": "Also accepts address_city or addressCity." }, "state": { "type": "string", "description": "Also accepts province, provinceOrState, address_state, or addressState." }, "postal_code": { "type": "string", "description": "Also accepts postalCode, postalOrZip, zip, address_zip, or addressZip." }, "countryCode": { "type": "string", "minLength": 2, "maxLength": 2, "default": "US", "description": "ISO 3166-1 alpha-2 country code. Defaults to US when omitted." } } }, "MailOrderStatus": { "type": "string", "enum": [ "queued", "document_preparing", "document_prepared", "submitted", "accepted", "in_transit", "delivered", "returned", "submission_pending", "failed", "canceled" ], "description": "Order timeline status. `submission_pending` means the fulfillment submit job entered a physical-mail safety window where PostalForm cannot blindly retry without risking duplicate mail; it requires reconciliation if it remains the current order status." }, "CustomerWebhookEventType": { "type": "string", "description": "Customer webhook event names emitted for fulfillment status changes. Replace `letter` with `postcard` for postcard mailpieces.", "enum": [ "postalform.letter.accepted", "postalform.letter.in_transit", "postalform.letter.delivered", "postalform.letter.returned", "postalform.letter.failed", "postalform.letter.canceled", "postalform.postcard.accepted", "postalform.postcard.in_transit", "postalform.postcard.delivered", "postalform.postcard.returned", "postalform.postcard.failed", "postalform.postcard.canceled" ], "x-enumDescriptions": { "postalform.letter.accepted": "Letter accepted for production or mailing after the order leaves PostalForm's preparation queue.", "postalform.letter.in_transit": "Letter entered the mail stream. The payload may include or update `mailpiece.tracking_number` when tracking is available.", "postalform.letter.delivered": "Letter reported delivered by the carrier or delivery network.", "postalform.letter.returned": "Letter returned or otherwise marked undeliverable.", "postalform.letter.failed": "Letter could not be produced or mailed. Inspect the order timeline and retry with a corrected request when appropriate.", "postalform.letter.canceled": "Letter canceled before delivery completion.", "postalform.postcard.accepted": "Postcard accepted for production or mailing after the order leaves PostalForm's preparation queue.", "postalform.postcard.in_transit": "Postcard entered the mail stream. The payload may include or update `mailpiece.tracking_number` when tracking is available.", "postalform.postcard.delivered": "Postcard reported delivered by the carrier or delivery network.", "postalform.postcard.returned": "Postcard returned or otherwise marked undeliverable.", "postalform.postcard.failed": "Postcard could not be produced or mailed. Inspect the order timeline and retry with a corrected request when appropriate.", "postalform.postcard.canceled": "Postcard canceled before delivery completion." } }, "CustomerWebhookPayload": { "type": "object", "description": "JSON body POSTed to customer webhook endpoints.", "properties": { "id": { "type": "string", "example": "evt_123" }, "type": { "$ref": "#/components/schemas/CustomerWebhookEventType" }, "data": { "type": "object", "properties": { "object": { "$ref": "#/components/schemas/Letter" } } }, "mailpiece": { "type": "object", "properties": { "status": { "type": "string", "nullable": true }, "tracking_number": { "type": "string", "nullable": true }, "tracking_status": { "type": "string", "nullable": true } } } } }, "WebhookDeliveryAttempt": { "type": "object", "properties": { "id": { "type": "string" }, "webhookEventId": { "type": "string" }, "endpointId": { "type": "string" }, "attemptNumber": { "type": "integer" }, "status": { "type": "string", "enum": [ "succeeded", "failed" ] }, "httpStatus": { "type": "integer" }, "responseBodySnippet": { "type": "string" }, "attemptedAt": { "type": "string", "format": "date-time" }, "nextRetryAt": { "type": "string", "format": "date-time" } } }, "CreditBalanceSnapshot": { "type": "object", "properties": { "available_cents": { "type": "integer" }, "reserved_cents": { "type": "integer" }, "currency": { "type": "string" }, "status": { "type": "string" } } } }, "parameters": { "DocumentId": { "name": "document_id", "in": "path", "required": true, "schema": { "type": "string" } }, "OrderId": { "name": "order_id", "in": "path", "required": true, "schema": { "type": "string" } }, "EventId": { "name": "event_id", "in": "path", "required": true, "schema": { "type": "string" } } } } }