{
  "openapi": "3.1.0",
  "info": {
    "title": "Notary Connect APIs",
    "version": "v1",
    "description": "The Notary Connect API (historically the \"Mobile Notary API\") lets signing services and title companies drive the Snapdocs scheduling platform from their own systems: list the clients and products an API key is provisioned for, create and update signing orders, upload and download order documents, and exchange comments.\n\n## Response format\n\nEach API key is provisioned with a fixed response format — `json` (default) or `xml` — chosen when the key is issued, not per request. All examples in this reference show the JSON shapes; XML keys receive the same fields wrapped in a singular root element (for example `<order>`). Requests made with an XML-format key must wrap order parameters in a root `<order>` element.\n\n## API key types\n\n| Key type | Scope | Can update order status |\n| --- | --- | --- |\n| **Company key** | All orders, clients, and products of the company | Yes |\n| **Client key** | A single client (branch) | No |\n\nSome fields and endpoints are restricted by key type; each is called out on the operation or field it affects."
  },
  "tags": [
    {
      "name": "API Key",
      "description": "Inspect the key used to authenticate."
    },
    {
      "name": "Clients",
      "description": "Clients (title office branches) the key can act on."
    },
    {
      "name": "Products",
      "description": "Signing products available to the key."
    },
    {
      "name": "Orders",
      "description": "Create, read, and update signing orders."
    },
    {
      "name": "Attachments",
      "description": "Upload documents to an order and download completed documents."
    },
    {
      "name": "Comments",
      "description": "Read and add comments on an order."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://app.snapdocs.com/mobile_notary_api/v1",
      "description": "Production"
    },
    {
      "url": "https://app.cs-demo0.snpd.io/mobile_notary_api/v1",
      "description": "Demo"
    }
  ],
  "paths": {
    "/api_key": {
      "get": {
        "operationId": "GetApiKeyInfo",
        "tags": [
          "API Key"
        ],
        "summary": "Get API key info",
        "description": "Returns the type and human-readable description of the API key used to authenticate the request. Useful for verifying a token and discovering whether it is a company key or a client key.",
        "responses": {
          "200": {
            "description": "Details of the authenticated API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "api_key": {
                      "$ref": "#/components/schemas/ApiKey"
                    }
                  }
                },
                "example": {
                  "api_key": {
                    "type": "client",
                    "description": "Acme Title - First National"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/clients": {
      "get": {
        "operationId": "ListClients",
        "tags": [
          "Clients"
        ],
        "summary": "List clients",
        "description": "Lists the clients (title office branches) the API key can create orders for, including each client's sellable products and active team members. A company key sees every active client of the company; a client key sees only its own client.",
        "responses": {
          "200": {
            "description": "The clients visible to the API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "clients": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Client"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/products": {
      "get": {
        "operationId": "ListProducts",
        "tags": [
          "Products"
        ],
        "summary": "List products",
        "description": "Lists the signing products available to the API key, paginated. A company key sees the company's generic products; a client key sees the products available to its client.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-based). Values below 1 are treated as 1.",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Results per page. Defaults to 25; capped at 100.",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100,
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of products with pagination metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "response": {
                      "type": "object",
                      "properties": {
                        "products": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ProductDetail"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/PaginationMeta"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "The company (or the client the key is scoped to) no longer exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error while listing products.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "post": {
        "operationId": "CreateOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Create order",
        "description": "Creates a signing order.\n\n- **Client keys** must supply `team_member_id` (or `owner_email` resolving to a team member); the order is created under the key's client.\n- **Company keys** may supply `client_id` to place the order under a specific client.\n- `product_id` is required.\n- `external_source` and `external_reference` can only be set at creation.\n\n### Callback events\n\nIf a callback URL is configured for your API key, Snapdocs sends an HTTP POST to that URL when one of these order lifecycle events occurs:\n\n- `notary_assigned` — a notary is assigned to the order.\n- `notary_removed` — the assigned notary is removed from the order.\n- `notary_fee_changed` — the notary fee changes. **Company keys only.**\n- `appointment_confirmed` — the signing appointment is confirmed.\n- `appointment_change_requested` — a change to the signing appointment is requested.\n- `documents_status_changed` — the order's document status (`attachment_status`) changes — for example, documents are emailed to the notary or downloaded.\n- `scanback_added` — the notary uploads a scanback document.\n- `status_changed` — the order's signing status changes (completed, canceled, on hold, did not sign, or reactivated).\n- `automator_stopped` — Snapdocs' automated notary search is stopped before a notary has been assigned.\n- `order_comment_added` — a comment is added to the order. **Company keys only.**\n\n- Callbacks are only sent for orders created through this API.\n- Requests are signed with HMAC-SHA1 via the [api-auth](https://github.com/mgomes/api_auth) scheme, delivered in an `Authorization: APIAuth <key_id>:<signature>` header.\n- The body is JSON or XML, matching the API key's configured response format (JSON by default); XML payloads are wrapped in a `<callback>` root element.\n- Respond with a 2xx status to acknowledge receipt. Deliveries that fail with a connection error are retried up to 5 times.\n- Callbacks are delivered a few seconds after the triggering event.\n\nSee the Callbacks section below for each event's full request schema.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/OrderResponseCreated"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "callbacks": {
          "notary_assigned": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "notary_assigned",
                "description": "Sent when a notary is assigned to the order.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "notary_removed": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "notary_removed",
                "description": "Sent when the assigned notary is removed from the order.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "notary_fee_changed": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "notary_fee_changed",
                "description": "Sent when the notary fee on the order changes. **Company keys only.**",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "appointment_confirmed": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "appointment_confirmed",
                "description": "Sent when the signing appointment is confirmed.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "appointment_change_requested": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "appointment_change_requested",
                "description": "Sent when a change to the signing appointment is requested.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "documents_status_changed": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "documents_status_changed",
                "description": "Sent when the order's document status (`attachment_status`) changes — for example, when documents are emailed to the notary or downloaded.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "scanback_added": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "scanback_added",
                "description": "Sent when the notary uploads a scanback document. The new document appears in `order.attachments` with `uploaded_by_notary: true`.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "status_changed": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "status_changed",
                "description": "Sent when the order's signing status changes (completed, canceled, on hold, did not sign, or reactivated).",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "automator_stopped": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "automator_stopped",
                "description": "Sent when Snapdocs' automated notary search is stopped for the order before a notary has been assigned.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderEventCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          },
          "order_comment_added": {
            "{yourCallbackEndpoint}": {
              "post": {
                "summary": "order_comment_added",
                "description": "Sent when a comment is added to the order. The payload includes an additional top-level `comment` object. **Company keys only.**",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/OrderCommentAddedCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Return any 2xx status to acknowledge receipt of the callback."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/orders/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/OrderId"
        }
      ],
      "get": {
        "operationId": "GetOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Get order",
        "description": "Returns the full order, including its current status, assigned notary (if any), attachments, and observer emails.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/OrderResponse"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "put": {
        "operationId": "UpdateOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Update order",
        "description": "Updates an existing order. Accepts the same fields as order creation except `external_source` and `external_reference` (creation-only). Fields omitted from the request are left unchanged. `PATCH` is also accepted.\n\nSending `participants` replaces the order's observer list with the supplied emails.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/OrderResponseAccepted"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{id}/update_status": {
      "put": {
        "operationId": "UpdateOrderStatus",
        "tags": [
          "Orders"
        ],
        "summary": "Update order status",
        "description": "Changes the signing status of an order. **Company keys only** — client keys receive a 400 error.\n\nThe `status` value is an action to perform, not a literal status: `complete`, `cancel`, `on_hold`, `did_not_sign`, or `reactivate` (returns an on-hold/terminal order to `open`).",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "complete",
                      "cancel",
                      "on_hold",
                      "did_not_sign",
                      "reactivate"
                    ],
                    "description": "The status action to apply to the order."
                  }
                }
              },
              "example": {
                "status": "complete"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/OrderResponse"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/attachments": {
      "post": {
        "operationId": "UploadAttachment",
        "tags": [
          "Attachments"
        ],
        "summary": "Upload attachment",
        "description": "Attaches a document to an order. Two request styles are supported:\n\n1. **Multipart upload** — send the file bytes as a form field named `file`.\n2. **Base64 JSON** — send `file.name` (filename with extension) and `file.base64` (base64-encoded content).\n\nFor client keys, the order must have a team member assigned.\n\nIf the company is configured to send documents to notaries automatically, uploading can trigger document release to the assigned notary.",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderIdParent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The document to attach."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "object",
                    "required": [
                      "name",
                      "base64"
                    ],
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "Filename including extension; the extension determines the content type.",
                        "examples": [
                          "closing_package.pdf"
                        ]
                      },
                      "base64": {
                        "type": "string",
                        "description": "Base64-encoded file content."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The attachment was created (or, for idempotent internal re-submissions, already existed).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "attachment": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "ID of the created attachment."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "attachment": {
                    "id": 8003
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/attachments/{id}": {
      "get": {
        "operationId": "DownloadAttachment",
        "tags": [
          "Attachments"
        ],
        "summary": "Download attachment",
        "description": "Redirects to a URL where the attachment's file can be downloaded. Use the `url` values returned on an order's `attachments` array to build these requests. The download is recorded (it can flip the order's `attachment_status` to `downloaded`).",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderIdParent"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The attachment ID.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the file's download URL. Follow the `Location` header to retrieve the bytes.",
            "headers": {
              "Location": {
                "description": "Temporary URL of the file.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/comments": {
      "parameters": [
        {
          "$ref": "#/components/parameters/OrderIdParent"
        }
      ],
      "get": {
        "operationId": "ListComments",
        "tags": [
          "Comments"
        ],
        "summary": "List comments",
        "description": "Lists the human-authored comments on an order. **Company keys only** — client keys receive a 401.\n\nAutomatically-added comments and internal notes (scheduler comments shared with no one) are excluded.",
        "responses": {
          "200": {
            "description": "The order's comments, oldest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Comment"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "post": {
        "operationId": "CreateComment",
        "tags": [
          "Comments"
        ],
        "summary": "Create comment",
        "description": "Adds a comment to an order on behalf of a team member.\n\n`commenter_email` must belong to an active team member of the key's company (company keys) or client (client keys); the comment is attributed to that person.\n\nSharing flags control who can see the comment and who is notified. For client keys, email notifications are always sent; for company keys they are controlled by `send_email_notification`.\n\nResponses are always JSON, regardless of the key's provisioned format.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "comment"
                ],
                "properties": {
                  "comment": {
                    "$ref": "#/components/schemas/CommentCreateRequest"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created comment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "comment": {
                      "$ref": "#/components/schemas/Comment"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "Validation error — for example a missing or unrecognized `commenter_email`, or a commenter who is not a team member of the company/client.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "errors": [
                    "commenter_email is required"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-AUTH-TOKEN",
        "description": "API token issued by Snapdocs. Requests without a valid, active token receive `401 Unauthorized` with an empty body."
      }
    },
    "parameters": {
      "OrderId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "The Snapdocs order ID.",
        "schema": {
          "type": "integer"
        }
      },
      "OrderIdParent": {
        "name": "order_id",
        "in": "path",
        "required": true,
        "description": "The Snapdocs order ID.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, invalid, or revoked API token. The response has no body."
      },
      "NotFound": {
        "description": "No order (or record) with this ID is visible to the API key."
      },
      "ValidationError": {
        "description": "The request could not be processed. `meta.errors` lists human-readable messages.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "meta": {
                "errors": [
                  "Product is required"
                ]
              }
            }
          }
        }
      },
      "OrderResponse": {
        "description": "The order.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OrderEnvelope"
            }
          }
        }
      },
      "OrderResponseCreated": {
        "description": "The created order.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OrderEnvelope"
            }
          }
        }
      },
      "OrderResponseAccepted": {
        "description": "The updated order.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OrderEnvelope"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "meta": {
            "type": "object",
            "properties": {
              "errors": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Human-readable error messages."
              }
            }
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "total_count": {
            "type": "integer",
            "description": "Total number of results across all pages."
          },
          "total_pages": {
            "type": "integer",
            "description": "Total number of pages."
          },
          "page": {
            "type": "integer",
            "description": "The current page."
          },
          "per_page": {
            "type": "integer",
            "description": "Results per page."
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "company",
              "client"
            ],
            "description": "Whether this is a company key (full access) or a client key (single client)."
          },
          "description": {
            "type": "string",
            "description": "Human-readable identification of the key's scope: the company name, or `Company - Client` for client keys.",
            "examples": [
              "Acme Title - First National"
            ]
          }
        }
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Client ID — use as `client_id` when creating orders with a company key."
          },
          "company_name": {
            "type": "string",
            "description": "The client's company name."
          },
          "products": {
            "type": "array",
            "description": "Products that can be ordered for this client.",
            "items": {
              "$ref": "#/components/schemas/ClientProduct"
            }
          },
          "team_members": {
            "type": "array",
            "description": "Active team members of this client — use their `id` as `team_member_id` when creating orders.",
            "items": {
              "$ref": "#/components/schemas/ClientTeamMember"
            }
          }
        }
      },
      "ClientProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Product ID — use as `product_id` when creating orders."
          },
          "product_name": {
            "type": "string",
            "description": "Display name of the product."
          },
          "cqc_title_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether Snapdocs Connect QC for title is enabled for this product."
          },
          "ron_signing": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether this product is a remote online notarization signing."
          },
          "client_fee": {
            "type": [
              "string",
              "number",
              "null"
            ],
            "description": "The fee charged to the client for this product, if configured."
          }
        }
      },
      "ClientTeamMember": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Team member ID — use as `team_member_id` when creating orders."
          },
          "full_name": {
            "type": "string",
            "description": "The team member's full name."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "The team member's email address."
          }
        }
      },
      "ProductDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Product ID — use as `product_id` when creating orders."
          },
          "product_name": {
            "type": "string",
            "description": "Display name of the product."
          },
          "client_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The client this product is specific to, or `null` for company-wide (generic) products."
          },
          "scanbacks_required": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether scanned-back documents are required after signing."
          },
          "attorney_required": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the signing must be performed by an attorney."
          },
          "witness_required": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether witnesses are required at the signing."
          },
          "witness_count": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Number of witnesses required, when applicable."
          },
          "ron_signing": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether this product is a remote online notarization signing."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the product was created (ISO 8601)."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the product was last updated (ISO 8601)."
          }
        }
      },
      "OrderWritableFields": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "description": "ID of the signing product (see List products / List clients). Required."
          },
          "client_id": {
            "type": "integer",
            "description": "ID of the client to place the order under. **Company keys only** — ignored for client keys (the key's own client is always used)."
          },
          "team_member_id": {
            "type": "integer",
            "description": "ID of the client team member (escrow officer) responsible for the order. Required for client keys unless `owner_email` resolves to a team member."
          },
          "owner_email": {
            "type": "string",
            "format": "email",
            "description": "Email of an existing Snapdocs team member to own the order — an alternative to `team_member_id`."
          },
          "escrow_number": {
            "type": "string",
            "description": "Your escrow / file number for the transaction."
          },
          "appointment_date": {
            "type": "string",
            "description": "Scheduled signing date. Accepts `d/m/yyyy` (e.g. `2/4/2018` = April 2) or ISO `yyyy-mm-dd`.",
            "examples": [
              "2018-04-02"
            ]
          },
          "appointment_time": {
            "type": "string",
            "description": "Scheduled signing time: a quarter-hour time such as `1:15 pm`, or one of the inexact values `morning`, `afternoon`, `evening`, `t_b_d`, `asap`.",
            "examples": [
              "1:15 pm"
            ]
          },
          "first_name": {
            "type": "string",
            "description": "Primary signer's first name."
          },
          "last_name": {
            "type": "string",
            "description": "Primary signer's last name."
          },
          "mobile_phone": {
            "type": "string",
            "description": "Primary signer's mobile phone number."
          },
          "home_phone": {
            "type": "string",
            "description": "Primary signer's home phone number."
          },
          "work_phone": {
            "type": "string",
            "description": "Primary signer's work phone number."
          },
          "signer_email": {
            "type": "string",
            "format": "email",
            "description": "Primary signer's email address."
          },
          "signing_street_address": {
            "type": "string",
            "description": "Street address where the signing takes place."
          },
          "signing_city": {
            "type": "string",
            "description": "City of the signing location."
          },
          "signing_state": {
            "type": "string",
            "description": "State of the signing location (2-letter code)."
          },
          "signing_zip": {
            "type": "string",
            "description": "ZIP code of the signing location."
          },
          "signing_location_details": {
            "type": "string",
            "description": "Additional details about the signing location."
          },
          "property_street_address": {
            "type": "string",
            "description": "Street address of the subject property, if different from the signing location."
          },
          "property_city": {
            "type": "string",
            "description": "City of the subject property."
          },
          "property_state": {
            "type": "string",
            "description": "State of the subject property (2-letter code)."
          },
          "property_zip": {
            "type": "string",
            "description": "ZIP code of the subject property."
          },
          "co_signer_first_name": {
            "type": "string",
            "description": "Co-signer's first name."
          },
          "co_signer_last_name": {
            "type": "string",
            "description": "Co-signer's last name."
          },
          "co_signer_home_phone": {
            "type": "string",
            "description": "Co-signer's home phone number."
          },
          "co_signer_mobile_phone": {
            "type": "string",
            "description": "Co-signer's mobile phone number."
          },
          "co_signer_work_phone": {
            "type": "string",
            "description": "Co-signer's work phone number."
          },
          "co_signer_email": {
            "type": "string",
            "format": "email",
            "description": "Co-signer's email address."
          },
          "special_instructions": {
            "type": "string",
            "description": "Instructions for the notary or scheduler."
          },
          "lender": {
            "type": "string",
            "description": "Name of the lender associated with the transaction."
          },
          "language_requirement": {
            "type": "string",
            "description": "Language the signing must be conducted in (e.g. `spanish`)."
          },
          "participants": {
            "type": "string",
            "description": "Comma-separated list of email addresses to add as order observers. On update, replaces the existing observer list."
          }
        }
      },
      "OrderCreateRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/OrderWritableFields"
          },
          {
            "type": "object",
            "required": [
              "product_id"
            ],
            "properties": {
              "external_source": {
                "type": "string",
                "description": "Identifier of your system creating the order. Can only be set at creation."
              },
              "external_reference": {
                "type": "string",
                "description": "Your system's unique reference for the order. Can only be set at creation."
              }
            }
          }
        ],
        "description": "Fields accepted when creating an order. XML-format keys must wrap these in a root `<order>` element."
      },
      "OrderUpdateRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/OrderWritableFields"
          }
        ],
        "description": "Fields accepted when updating an order — the create fields minus `external_source`/`external_reference`. Omitted fields are unchanged."
      },
      "OrderEnvelope": {
        "type": "object",
        "properties": {
          "order": {
            "$ref": "#/components/schemas/Order"
          }
        }
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Unique Snapdocs order ID."
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "completed",
              "canceled",
              "did_not_sign",
              "on_hold"
            ],
            "description": "Current signing status of the order."
          },
          "client_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID of the client (title office branch) the order belongs to."
          },
          "product_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID of the signing product."
          },
          "team_member_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID of the client team member responsible for the order."
          },
          "escrow_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "Escrow / file number for the transaction."
          },
          "appointment_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Scheduled signing date (`yyyy-mm-dd`)."
          },
          "appointment_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scheduled signing time (`1:15 pm`, or `morning` / `afternoon` / `evening` / `t_b_d` / `asap`)."
          },
          "first_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary signer's first name."
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary signer's last name."
          },
          "mobile_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary signer's mobile phone number."
          },
          "home_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary signer's home phone number."
          },
          "work_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary signer's work phone number."
          },
          "appointment_confirmation_status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "unconfirmed",
              "confirmed",
              "change_requested",
              "signer_unreachable",
              null
            ],
            "description": "Whether the signer has confirmed the appointment. Resets to `unconfirmed` when the appointment date/time changes."
          },
          "attachment_status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "sent_by_client",
              "sent",
              "notary_picked_up_docs",
              "overnighted",
              "at_closing",
              "emailed_to_notary",
              "direct_links",
              "downloaded",
              null
            ],
            "description": "How documents reached (or will reach) the notary. `downloaded` means the notary has downloaded all documents; `null` means documents have not been sent."
          },
          "signer_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary signer's email address."
          },
          "signing_street_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Street address of the signing location."
          },
          "signing_location_details": {
            "type": [
              "string",
              "null"
            ],
            "description": "Additional details about the signing location."
          },
          "signing_city": {
            "type": [
              "string",
              "null"
            ],
            "description": "City of the signing location."
          },
          "signing_state": {
            "type": [
              "string",
              "null"
            ],
            "description": "State of the signing location (2-letter code)."
          },
          "signing_zip": {
            "type": [
              "string",
              "null"
            ],
            "description": "ZIP code of the signing location."
          },
          "property_street_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Street address of the subject property."
          },
          "property_city": {
            "type": [
              "string",
              "null"
            ],
            "description": "City of the subject property."
          },
          "property_state": {
            "type": [
              "string",
              "null"
            ],
            "description": "State of the subject property."
          },
          "property_zip": {
            "type": [
              "string",
              "null"
            ],
            "description": "ZIP code of the subject property."
          },
          "co_signer_first_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Co-signer's first name."
          },
          "co_signer_last_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Co-signer's last name."
          },
          "co_signer_home_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Co-signer's home phone number."
          },
          "co_signer_mobile_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Co-signer's mobile phone number."
          },
          "co_signer_work_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Co-signer's work phone number."
          },
          "co_signer_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Co-signer's email address."
          },
          "external_source": {
            "type": [
              "string",
              "null"
            ],
            "description": "Identifier of the external system that created the order."
          },
          "external_reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "The external system's reference for the order."
          },
          "notary": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Notary"
              },
              {
                "type": "null"
              }
            ],
            "description": "The assigned notary, or `null` if none is assigned yet."
          },
          "owner_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email of the team member who owns the order."
          },
          "attachments": {
            "type": "array",
            "description": "Documents attached to the order.",
            "items": {
              "$ref": "#/components/schemas/Attachment"
            }
          },
          "special_instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instructions for the notary or scheduler."
          },
          "total_notary_fee": {
            "type": [
              "number",
              "string",
              "null"
            ],
            "description": "Total fee payable to the notary. **Company keys only** — omitted from responses to client keys."
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "description": "Email addresses of the order's observers."
          },
          "language_requirement": {
            "type": [
              "string",
              "null"
            ],
            "description": "Language the signing must be conducted in."
          }
        }
      },
      "Notary": {
        "type": "object",
        "description": "The notary assigned to an order. For client keys, `email`, `phone`, and the payment address fields are omitted unless the order's product is configured to share them.",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Notary ID."
          },
          "first_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's first name."
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's last name."
          },
          "company_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's business name."
          },
          "payment_street_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's payment street address."
          },
          "payment_city": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's payment address city."
          },
          "payment_state": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's payment address state."
          },
          "payment_zip": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's payment address ZIP code."
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notary's confirmation phone number."
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "description": "Notary's email address."
          }
        }
      },
      "Attachment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Attachment ID."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Filename of the attachment."
          },
          "url": {
            "type": "string",
            "description": "Relative path to the download endpoint for this attachment (append to the host, e.g. `https://app.snapdocs.com/mobile_notary_api/v1/orders/123/attachments/456`)."
          },
          "last_downloaded_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the attachment was last downloaded, or `null` if never."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the attachment was uploaded."
          },
          "uploaded_by_notary": {
            "type": "boolean",
            "description": "`true` when the notary uploaded the document (e.g. a scanback), `false` when it was uploaded by the client or company."
          }
        }
      },
      "Comment": {
        "type": "object",
        "properties": {
          "order_id": {
            "type": "integer",
            "description": "ID of the order the comment belongs to."
          },
          "commenter": {
            "type": "string",
            "description": "Full name of the person who wrote the comment, or `Unavailable`."
          },
          "role": {
            "type": "string",
            "description": "The commenter's role: `Scheduler` (company team member), `Client` (client team member), or another commenter type such as `Notary`."
          },
          "text": {
            "type": "string",
            "description": "The comment text."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the comment was created."
          },
          "shared_with_client": {
            "type": "boolean",
            "description": "Whether the comment is visible to the client's team members."
          },
          "shared_with_consumer": {
            "type": "boolean",
            "description": "Whether the comment is visible to the consumer/signer."
          },
          "shared_with_lender": {
            "type": "boolean",
            "description": "Whether the comment is visible to the lender."
          },
          "shared_with_notary": {
            "type": "boolean",
            "description": "Whether the comment is visible to the assigned notary."
          },
          "shared_with_settlement_agent": {
            "type": "boolean",
            "description": "Whether the comment is visible to the settlement agent."
          }
        }
      },
      "CommentCreateRequest": {
        "type": "object",
        "required": [
          "text",
          "commenter_email"
        ],
        "properties": {
          "text": {
            "type": "string",
            "description": "The comment text."
          },
          "commenter_email": {
            "type": "string",
            "format": "email",
            "description": "Email of the team member the comment is posted as. Must be an active team member of the key's company (company keys) or client (client keys)."
          },
          "send_email_notification": {
            "type": "boolean",
            "description": "Whether to email the comment to its audience. Applies to company keys; client-key comments always send email notifications."
          },
          "shared_with_client": {
            "type": "boolean",
            "description": "Share the comment with the client's team members."
          },
          "shared_with_consumer": {
            "type": "boolean",
            "description": "Share the comment with the consumer/signer."
          },
          "shared_with_notary": {
            "type": "boolean",
            "description": "Share the comment with the assigned notary (also triggers an SMS when email notification is enabled)."
          },
          "shared_with_lender": {
            "type": "boolean",
            "description": "Share the comment with the lender."
          },
          "shared_with_settlement_agent": {
            "type": "boolean",
            "description": "Share the comment with the settlement agent."
          }
        }
      },
      "OrderEventCallback": {
        "type": "object",
        "description": "The payload delivered to your callback endpoint when an order lifecycle event occurs. `order` is the same representation returned by the Get Order endpoint.",
        "required": [
          "event",
          "order"
        ],
        "properties": {
          "event": {
            "type": "string",
            "description": "The event that triggered this callback.",
            "enum": [
              "notary_assigned",
              "notary_removed",
              "notary_fee_changed",
              "appointment_confirmed",
              "appointment_change_requested",
              "documents_status_changed",
              "scanback_added",
              "status_changed",
              "automator_stopped",
              "order_comment_added"
            ]
          },
          "order": {
            "$ref": "#/components/schemas/Order"
          }
        }
      },
      "OrderCommentAddedCallback": {
        "description": "The payload delivered for `order_comment_added` events. Adds `comment` to the standard event payload.",
        "allOf": [
          {
            "$ref": "#/components/schemas/OrderEventCallback"
          },
          {
            "type": "object",
            "properties": {
              "comment": {
                "$ref": "#/components/schemas/Comment"
              }
            }
          }
        ]
      }
    }
  }
}