Signatures

Envelope Attachment Upload

POST
/signatures/envelope/{envelopeId}/attachment/upload

Uploads one or more attachments to a specific envelope (e.g. supporting files, contracts, or other materials providing context for digital signing). Form-data only — there is no JSON/raw-body alternative for this operation. No file-extension or content-type validation of any kind is performed by the backend — this is the widest-open upload operation in the group; any file type is accepted. Genuinely supports TWO alternate, mutually exclusive auth contracts (intentional dual-mode design, not a bug), identical in structure to the sibling download operation: (1) anonymous mode — a Guid-parseable tid query parameter is present, and no Authorization header is required; or (2) authenticated mode — no valid tid is supplied, so a real Authorization bearer token IS required, and the caller must be the envelope's creator or a signer on it. After upload, each file is assigned a unique id that can be referenced in processes like envelope creation. Max File Size: Production 20 MB, Staging 10 MB.

Authorization

AuthorizationBearer <token>

JWT token to authenticate the request.

In: header

X-Api-Key<token>

API key, sent as a request header.

In: header

Path Parameters

envelopeId*string

GUID of the envelope to attach the file(s) to.

Formatuuid

Query Parameters

tid?string

Transaction token identifying a specific recipient+envelope pair. When present and Guid-parseable, selects anonymous mode and no Authorization header is required. When absent or not Guid-parseable, authenticated mode applies and Authorization is required instead.

Formatuuid

Header Parameters

X-Service-Authorization?string

Service-to-service auth token, used as an alternative to Authorization in authenticated mode.

X-Client-Authorization?string

Client auth token, used as an alternative to Authorization in authenticated mode.

X-Email?string

Caller email, used for identity resolution in authenticated mode.

X-OAuth-Flow?string

Indicates which OAuth flow variant issued the Authorization token, in authenticated mode.

X-Origin?string

Free-form caller-supplied origin identifier. Not validated; echoed back verbatim into the response envelope's origin field. Optional.

X-Storage-Type*string

Container-type key for the uploaded attachment. Expected value is envelope-attachment.

Request Body

multipart/form-data

TypeScript Definitions

Use the request body type in TypeScript.

body?unknown

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/signatures/envelope/3fa85f64-5717-4562-b3fc-2c963f66afa6/attachment/upload" \  -H "X-Origin: https://app.mavenmule.com" \  -H "X-Storage-Type: envelope-attachment" \  -F file="[]"
{  "result": {    "data": {      "files": [        {          "id": "76bb2621-b1b1-4d47-9132-c4d1e5f60abc",          "fileName": "SampleAttachment.jpg"        }      ]    },    "statusCode": 201,    "message": "Created"  },  "origin": "https://dev.headless.mavenmule.com/signatures/envelope/7a5d60-a222-4c3e490ef1/attachment/upload",  "dateTime": "2025-11-03T06:48:58.0000000+00:00",  "operationId": "ea5716c820f26295b44c2fb2"}
{  "error": {    "statusCode": 400,    "message": "Request must be multipart/form-data.",    "innerErrors": [      {        "code": "FORM_DATA_EXPECTED",        "message": "Request must be multipart/form-data.",        "userMessage": "Request must be multipart/form-data."      }    ]  },  "origin": "https://app.mavenmule.com",  "dateTime": "2026-07-14T09:32:15.0000000+00:00",  "operationId": "3a4b5c6d7e8f90112233445566778899"}
{  "error": {    "statusCode": 401,    "message": "The request could not be authenticated.",    "innerErrors": [      {        "code": "UNAUTHORIZED",        "message": "The request could not be authenticated.",        "userMessage": "Your session has expired or is invalid. Please sign in again."      }    ]  },  "origin": "https://app.mavenmule.com",  "dateTime": "2026-07-14T09:32:15.0000000+00:00",  "operationId": "3a4b5c6d7e8f90112233445566778899"}
{  "error": {    "statusCode": 403,    "message": "The envelope owner's subscription is not active.",    "innerErrors": [      {        "code": "ENVELOPE_OWNER_INVALID_SUBSCRIPTION",        "message": "The envelope owner's subscription is not active.",        "userMessage": "This envelope can't accept uploads right now."      }    ]  },  "origin": "https://app.mavenmule.com",  "dateTime": "2026-07-14T09:32:15.0000000+00:00",  "operationId": "3a4b5c6d7e8f90112233445566778899"}
{  "error": {    "statusCode": 404,    "message": "Envelope not found for the supplied user and envelope id.",    "innerErrors": [      {        "code": "ENVELOPE_NOT_FOUND_USER_AND_ENVELOPE_ID",        "message": "Envelope not found for the supplied user and envelope id.",        "userMessage": "We couldn't find that envelope, or you don't have access to it."      }    ]  },  "origin": "https://app.mavenmule.com",  "dateTime": "2026-07-14T09:32:15.0000000+00:00",  "operationId": "3a4b5c6d7e8f90112233445566778899"}
{  "error": {    "statusCode": 500,    "message": "Failed to persist the uploaded file to storage.",    "innerErrors": [      {        "code": "FILE_UPLOAD_FAILED",        "message": "Failed to persist the uploaded file to storage.",        "userMessage": "Something went wrong while uploading. Please try again or contact support."      }    ]  },  "origin": "https://app.mavenmule.com",  "dateTime": "2026-07-14T09:32:15.0000000+00:00",  "operationId": "3a4b5c6d7e8f90112233445566778899"}