Every API here is available over the APIs.io API and to AI agents over MCP.
{
"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
# --- truncated at 32 KB (61 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/postalform-com/refs/heads/main/openapi/postalform-com-projects-openapi.json