{
  "openapi": "3.0.3",
  "info": {
    "version": "v1",
    "title": "Document Sending API",
    "description": "The Document Sending API allows integration with the document sending platform\nto deliver quote documents (PDFs) to customers via SMS and/or Email,\nand track engagement events.\n\n## Authentication\n\nAll API requests require authentication. Details will be provided later.\n\n## Error Handling\n\nAll error responses follow the standard ApiError format with:\n- `error.code` - Machine-readable error code (e.g., `ValidationError`, `InternalServerError`)\n- `error.message` - Human-readable description\n- `error.innerErrors` - Optional nested errors for field-level validation details\n\n## Callbacks\n\nAfter a document sending is initiated, lifecycle and engagement events are delivered\nto the callback URL provided in the request as POST requests with a JSON body.\nSee the callbacks section on the Initiate endpoint for the payload schema and examples."
  },
  "servers": [
    {
      "url": "https://api.example.com",
      "description": "TODO: Replace with actual server URLs once environments are provisioned"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "DocumentSending"
    }
  ],
  "paths": {
    "/api/documentSending": {
      "post": {
        "tags": [
          "DocumentSending"
        ],
        "summary": "Initiate document sending",
        "description": "Starts the process of sending a document (PDF) to a customer via one or more delivery methods (SMS, Email, or both).\n\n**What happens after initiation:**\n1. The document is validated and stored\n2. Organization settings are resolved (templates, send-window, expiry)\n3. A hosted document link is generated\n4. Delivery channels are processed (Email send, SMS send with quiet-hours scheduling)\n5. Lifecycle and engagement events are sent to the provided callback URL\n\n**Dual-channel semantics:**\nWhen both SMS and Email are requested, both channels share the same hosted document link.\nPartial success is valid: one channel may complete while the other is blocked or failed.",
        "operationId": "DocumentSending_Post",
        "requestBody": {
          "required": true,
          "description": "Document sending request with recipient, initiator, organization, callback URL, and PDF file",
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/InitiateDocumentSendingRequest"
              },
              "encoding": {
                "file": {
                  "contentType": "application/pdf"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document sending initiated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documentSendingId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Unique identifier for the document sending request"
                    }
                  },
                  "required": [
                    "documentSendingId"
                  ]
                },
                "example": {
                  "documentSendingId": "619c271f-51b8-773f-865c-fe5c71e5c9cb"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "ValidationError",
                    "message": "Initiate document sending: Provided file is not a valid PDF document"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "InternalServerError",
                    "message": "Initiate document sending: Unknown server error"
                  }
                }
              }
            }
          }
        },
        "callbacks": {
          "documentSendingEvent": {
            "{$request.body#/callbackUrl}": {
              "post": {
                "tags": [
                  "DocumentSending"
                ],
                "summary": "Document sending event callback",
                "description": "Sent to the callback URL provided in the initiate request whenever a lifecycle\nor engagement event occurs.\n\n**Document-level events** (no deliveryMethod):\n`sending`, `linkOpened`, `fileDownloaded`, `failed`,\n`clickedShowContacts`, `clickedEmail`, `clickedCall`, `clickedSendSms`\n\n**Channel-specific events** (include deliveryMethod):\n`sent`, `scheduled`, `providerFailed`",
                "operationId": "Webhook_DocumentSendingEvent",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/DocumentSendingCallback"
                      },
                      "examples": {
                        "linkOpened": {
                          "summary": "Customer opened the document link",
                          "value": {
                            "documentSendingId": "619c271f-51b8-773f-865c-fe5c71e5c9cb",
                            "documentSendingEvent": "linkOpened",
                            "timestamp": "2026-06-01T12:00:00Z"
                          }
                        },
                        "smsSent": {
                          "summary": "SMS was sent successfully",
                          "value": {
                            "documentSendingId": "619c271f-51b8-773f-865c-fe5c71e5c9cb",
                            "documentSendingEvent": "sent",
                            "timestamp": "2026-06-01T12:05:00Z",
                            "deliveryMethod": "sms"
                          }
                        },
                        "smsScheduled": {
                          "summary": "SMS scheduled for later send",
                          "value": {
                            "documentSendingId": "619c271f-51b8-773f-865c-fe5c71e5c9cb",
                            "documentSendingEvent": "scheduled",
                            "timestamp": "2026-06-01T12:00:00Z",
                            "deliveryMethod": "sms",
                            "scheduledTime": "2026-06-02T09:00:00Z"
                          }
                        }
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Event received successfully"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiError": {
        "type": "object",
        "description": "Standard error response wrapper returned by the API for all error scenarios",
        "properties": {
          "error": {
            "description": "Error details containing error code, message and optional nested errors",
            "allOf": [
              {
                "$ref": "#/components/schemas/Error"
              }
            ],
            "type": "object"
          }
        },
        "example": {
          "error": {
            "code": "ValidationError",
            "message": "Validation failed for one or more fields",
            "innerErrors": [
              {
                "code": "RequiredField",
                "message": "The 'email' field is required"
              }
            ]
          }
        }
      },
      "Error": {
        "type": "object",
        "description": "Represents an error with a code, human-readable message, and optional nested errors",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true,
            "description": "Machine-readable error code for programmatic error handling",
            "example": "ValidationError"
          },
          "message": {
            "type": "string",
            "nullable": true,
            "description": "Human-readable error message describing what went wrong",
            "example": "The email address is not valid"
          },
          "innerErrors": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/Error"
                }
              ]
            },
            "nullable": true,
            "description": "Nested errors providing additional details about the failure (e.g., validation errors for specific fields)"
          }
        },
        "example": {
          "code": "ValidationError",
          "message": "Request validation failed",
          "innerErrors": [
            {
              "code": "RequiredField",
              "message": "The 'email' field is required"
            },
            {
              "code": "InvalidFormat",
              "message": "The 'phoneNumber' format is invalid"
            }
          ]
        }
      },
      "InitiateDocumentSendingRequest": {
        "type": "object",
        "description": "Request to initiate document sending to a customer",
        "required": [
          "organizationCode",
          "initiator",
          "recipient",
          "file",
          "callbackUrl"
        ],
        "properties": {
          "organizationCode": {
            "type": "string",
            "description": "Organization code used to resolve configuration",
            "example": "DEFAULT"
          },
          "initiator": {
            "$ref": "#/components/schemas/DocumentSendingInitiator"
          },
          "recipient": {
            "$ref": "#/components/schemas/DocumentSendingRecipient"
          },
          "file": {
            "type": "string",
            "format": "binary",
            "description": "PDF document to be sent to the customer"
          },
          "callbackUrl": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS endpoint that will receive document sending event updates",
            "example": "https://integrating-service.example.com/webhooks/document-sending"
          }
        }
      },
      "InitiateDocumentSendingResponse": {
        "type": "object",
        "properties": {
          "documentSendingId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "additionalProperties": false
      },
      "DocumentSendingInitiator": {
        "type": "object",
        "description": "Information about the agent initiating the document sending",
        "required": [
          "fullName",
          "phoneNumber",
          "email"
        ],
        "properties": {
          "fullName": {
            "type": "string",
            "description": "Agent name, used on hosted pages and templates",
            "example": "Jane Smith"
          },
          "phoneNumber": {
            "type": "string",
            "description": "Agent phone number in E.164 format, used on hosted pages and Document Page Button actions",
            "example": "+11234567890"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Agent email address, used on hosted pages, as the public agent identifier, and as the candidate email sender identity",
            "example": "jane.smith@example.com"
          }
        }
      },
      "DocumentSendingRecipient": {
        "type": "object",
        "description": "Information about the recipient customer",
        "required": [
          "fullName"
        ],
        "properties": {
          "fullName": {
            "type": "string",
            "description": "Full name of the recipient customer, used for templates and customer context",
            "example": "John Doe"
          },
          "phoneNumber": {
            "type": "string",
            "nullable": true,
            "description": "Recipient phone number in E.164 format. Required when SMS delivery is intended. If provided, the document will be sent to this number.",
            "example": "+10987654321"
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "Recipient email address. Required when Email delivery is intended. If provided, the document will be sent to this email.",
            "example": "john.doe@example.com"
          }
        }
      },
      "DocumentSendingCallback": {
        "type": "object",
        "description": "Event payload sent to the callback URL when a document sending lifecycle or engagement event occurs",
        "required": [
          "documentSendingId",
          "documentSendingEvent",
          "timestamp"
        ],
        "properties": {
          "documentSendingId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the document sending request",
            "example": "619c271f-51b8-773f-865c-fe5c71e5c9cb"
          },
          "documentSendingEvent": {
            "type": "string",
            "description": "Type of the event",
            "enum": [
              "sending",
              "sent",
              "linkOpened",
              "fileDownloaded",
              "failed",
              "clickedShowContacts",
              "clickedEmail",
              "clickedCall",
              "clickedSendSms",
              "scheduled",
              "providerFailed"
            ],
            "example": "linkOpened"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the event (ISO 8601)",
            "example": "2026-06-01T12:00:00Z"
          },
          "deliveryMethod": {
            "type": "string",
            "description": "The delivery channel this event applies to. Present for channel-specific events (sent, scheduled, providerFailed).",
            "enum": [
              "sms",
              "email"
            ],
            "example": "sms"
          },
          "scheduledTime": {
            "type": "string",
            "format": "date-time",
            "description": "Scheduled send time. Present when documentSendingEvent is \"scheduled\".",
            "example": "2026-06-01T14:00:00Z"
          }
        }
      }
    }
  }
}