Complete reference for the Mocha Signature external API — every endpoint, request field, response body, webhook payload and status code.
Base URLs, authentication and the endpoint index.
All endpoints are POST with a JSON body — including the read-only ones — and every request must carry both the X-Tenant and Api-Key headers. Operations are scoped to your own tenant account.
| Environment | Base URL |
|---|---|
| UAT | https://services.us.uat.mochatechnologies.com/signature/api/V1 |
| Production | https://services.us.mochatechnologies.com/signature/api/V1 |
| Group | Endpoint | Purpose |
|---|---|---|
| Templates | /get-template-by-user | List the templates available to your account. |
| Templates | /get-template-detail | Read a template's recipient roles and privileges. |
| Envelopes | /send-envelop | Create an envelope from a template and email it out for signing. |
| Envelopes | /envelop-tracking | Track an envelope and each recipient's state. |
| Webhooks | /webhook/deliveries | Inspect the delivery log for a single webhook attempt. |
| Additional | /get-signing-links | Per-recipient signing URLs for an envelope. |
| Additional | /get-template-by-doc-code | List templates keyed on document_id instead of user. |
| Additional | /insert-template-field | Copy a template's field definitions onto an existing envelope. |
status as a boolean plus a separate status_code, others return status as the numeric HTTP code. The HTTP status code is always authoritative; read data for the payload.Templates — list everything available to the account.
Fetches all templates associated with the user account. Each item includes pdf_preview, a pre-signed S3 URL to the template PDF that is valid for 10 minutes — fetch it promptly or re-request the list. pdf_preview is null when the underlying object is missing from storage.
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | Required | The account's user identifier. |
template_type | string | null | Optional | Optional filter on the template's type, e.g. contract. |
{
"user_id": "acf28c4584f007dca67b"
}Returns the template list, which may be empty. See TemplateListItem in the Schema Reference.
{
"status_code": 200,
"status": true,
"message": "Template record exist.",
"data": [
{
"template_id": "73766101002022",
"user_id": "acf28c4584f007dca67b",
"document_id": "1002022",
"title": "Non-Disclosure Agreement",
"description": "Standard mutual NDA",
"total_pages": 3,
"user_name": "Jane",
"email": "jane@example.com",
"job": "Legal Counsel",
"industry": "Technology",
"pdf_path": "acf28c4584f007dca67b/documents/73766101002022/73766101002022.pdf",
"pdf_preview": "https://s3.amazonaws.com/...?X-Amz-Expires=600&X-Amz-Signature=..."
}
]
}| Status | Meaning |
|---|---|
| 200 | Template list (possibly empty). |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 404 | Tenant not found, or the key's user has no email on record. |
| 422 | Validation failed. msg names the offending fields. |
| 500 | Unexpected failure. error carries the reason. |
| 503 | Authentication dependency unreachable. Safe to retry. |
Templates — read the recipient contract before sending.
Retrieves a specific template's configuration, including the recipient roles it expects. recipients_role and required_recipient define the contract for Send Envelope: you must supply exactly these roles, and exactly that many recipients.
| Field | Type | Required | Description |
|---|---|---|---|
template_id | string | Required | Identifier shown in the Templates list in the web app. |
{
"template_id": "73766101002022"
}{
"status": 200,
"message": "Template record exist.",
"data": {
"template_id": "73766101002022",
"title": "Non-Disclosure Agreement",
"discription": "Standard mutual NDA",
"status": 1,
"required_recipient": 2,
"recipients_role": ["Signer 1", "Approver"]
}
}template_id the API replies 204. Per HTTP semantics the body of a 204 is not transmitted — branch on the status code, not on the body.| Status | Meaning |
|---|---|
| 200 | Template found. |
| 204 | No template maps to the supplied template_id. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 404 | Tenant not found, or the key's user has no email on record. |
| 422 | Validation failed. msg names the offending fields. |
| 500 | Unexpected failure. error carries the reason. |
| 503 | Authentication dependency unreachable. Safe to retry. |
Envelopes — create an envelope from a template and email it out.
Creates an envelope from a template and emails it to the recipients for signing. Recipients who do not yet exist as users are provisioned automatically and added to the sender's contacts.
recipients_role must equal required_recipient, and every role value must appear in the template's recipients_role list. A mismatch fails the request with a 500.| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | Required | Sending account's user identifier. |
company_name | string | Required | Sender's company name; also used when auto-provisioning new recipients. |
email_subject | string | Required | Subject line of the signing invitation email. |
message | string | Required | Body of the invitation email. Declared optional in validation but enforced downstream — omitting it returns 422, so always send it. |
template_id | string | Required | Template to build the envelope from. |
recipients_role | RecipientRole[] | Required | One entry per template recipient role, each with role, name and email. |
metadata | object | null | Optional | Free-form object stored with the envelope and echoed back verbatim in every webhook payload. Use it to carry your own correlation ids. |
file_path | string | null | Optional | Optional override for the document to send. Accepts a base64-encoded PDF (raw, or a data:application/pdf;base64,… URI). Omit it — the normal case — to use the template's own PDF. |
status | string | null | Optional | Reserved. Accepted for backwards compatibility and currently has no effect. |
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Required | Must match one of the template's recipient role titles exactly. |
name | string | Required | Recipient's name. Used as the first name when provisioning a new user. |
email | string (email) | Required | Recipient's email. If no account exists for it, a user and a sender-side contact are created automatically. |
{
"user_id": "acf28c4584f007dca67b",
"company_name": "Mocha Technologies",
"email_subject": "Please sign the Non-Disclosure Agreement",
"message": "Kindly review and sign the attached document.",
"template_id": "73766101002022",
"recipients_role": [
{
"role": "Signer 1",
"name": "John Doe",
"email": "john.doe@example.com"
},
{
"role": "Approver",
"name": "Alice Smith",
"email": "alice.smith@example.com"
}
],
"metadata": {
"order_id": "ORD-10021",
"source": "crm"
}
}{
"status": true,
"message": "Send envelop successfully!",
"envelope_id": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc",
"status_code": 200
}Returned when processing fails: the template could not be verified, the recipient roles could not be mapped to the template's roles, or provisioning a recipient failed. error carries the reason.
{
"status": false,
"message": "Something went wrong",
"error": "Recipients role can not map with required template roles.",
"status_code": 500
}| Status | Meaning |
|---|---|
| 200 | Envelope created and emailed to the recipients. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 404 | Tenant not found. |
| 422 | Validation failed, or a required value was missing — user_id, template_id, recipients_role, email_subject and message are all enforced at this stage. |
| 500 | Processing failed. Most commonly the recipient roles did not map to the template's roles. |
| 503 | Authentication dependency unreachable. Safe to retry. |
Envelopes — current state of the envelope and each recipient.
Tracks an envelope and each recipient's state. Use it to render progress in your own UI, and as the reconciliation fallback if you miss a webhook.
envelop_id (single e), while Send Envelope returns it as envelope_id. Map the value across that difference.| Field | Type | Required | Description |
|---|---|---|---|
envelop_id | string | Required | The envelope_id returned by Send Envelope. |
{
"envelop_id": "23b89b780dd1ff7b6885a684483a37ef"
}{
"status": 200,
"message": "Envelope tracking fetched successfully.",
"data": {
"envelope_id": "23b89b780dd1ff7b6885a684483a37ef",
"mail_status": "Email Sent",
"envelope_completion_status": "Pending",
"recipients": [
{
"recipient_name": "John Doe",
"recipient_email": "john.doe@example.com",
"status": "Completed",
"decline_reason": null,
"viewed_at": "2026-08-03 09:41:02",
"completed_at": "2026-08-03 09:44:37"
},
{
"recipient_name": "Alice Smith",
"recipient_email": "alice.smith@example.com",
"status": "Pending Signature",
"decline_reason": null,
"viewed_at": null,
"completed_at": null
}
]
}
}| Field | Possible values |
|---|---|
mail_status | Email Sent, Email Failed |
envelope_completion_status | Pending, Completed, Rejected (a recipient declined), N/A |
recipients[].status | Pending Signature, Completed, Declined, N/A |
| Status | Meaning |
|---|---|
| 200 | Tracking data for the envelope. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 404 | No envelope matches the supplied envelop_id. |
| 422 | Validation failed. |
| 500 | Unexpected failure. |
| 503 | Authentication dependency unreachable. |
What Mocha Signature POSTs to your endpoint.
Configure your endpoint in the web app under Settings → Custom Webhook. Two events are delivered, both signed with HMAC-SHA256 over the raw request body. Full setup and verification instructions are in Getting Started → Webhooks.
Delivered once every required recipient has completed the envelope. data.document.download_url is a pre-signed S3 link to the finished PDF, valid for 15 minutes — download and store the file on receipt rather than persisting the URL.
POST https://your-endpoint.example.com/hooks/mocha-signature
X-Webhook-Event: document.completed
X-Webhook-Delivery-Id: bd142d9e-31f6-459f-b8d8-5c5cb902fbd9
X-Webhook-Timestamp: 2026-08-03T10:24:11.482000Z
X-Authorization-Digest: HMACSHA256
X-Webhook-Signature-1: <base64 HMAC-SHA256 of the raw body, secret #1>
{
"event": "document.completed",
"data": {
"user_id": "acf28c4584f007dca67b",
"envelop_id": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc",
"status": "completed",
"generated_at": "2026-08-03T10:24:11.000000Z",
"metadata": {
"order_id": "ORD-10021",
"source": "crm"
},
"document": {
"file_name": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc.pdf",
"download_url": "https://s3.amazonaws.com/...?X-Amz-Expires=900&X-Amz-Signature=...",
"mime_type": "application/pdf"
}
},
"timestamp": "2026-08-03T10:24:11.482000Z"
}Delivered when a recipient declines or rejects the envelope. The signing flow stops at that point; remaining recipients are not asked to sign. Use Envelope Tracking to read which recipient declined and their decline_reason.
{
"event": "document.declined",
"data": {
"user_id": "acf28c4584f007dca67b",
"envelop_id": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc",
"status": "declined",
"generated_at": "2026-08-03T11:02:56.000000Z",
"metadata": {
"order_id": "ORD-10021"
},
"document": {
"file_name": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc.pdf",
"download_url": "https://s3.amazonaws.com/...?X-Amz-Expires=900&X-Amz-Signature=...",
"mime_type": "application/pdf"
}
},
"timestamp": "2026-08-03T11:02:56.913000Z"
}| Header | Required | Description |
|---|---|---|
X-Webhook-Event | Yes | document.completed or document.declined. |
X-Webhook-Delivery-Id | Yes | Unique id for this delivery. Store it — it is the lookup key for Webhook Deliveries. |
X-Webhook-Timestamp | Yes | ISO-8601 time the delivery was sent. |
X-Authorization-Digest | Yes | Signature algorithm — always HMACSHA256. |
X-Webhook-Signature-1 | Yes | Base64 HMAC-SHA256 of the raw request body, computed with your first active secret. |
X-Webhook-Signature-2 | No | Present when a second secret key is active. Accept the request if any supplied signature matches. |
2xx to acknowledge. Non-2xx — or a timeout past 15 seconds — marks the delivery failed and schedules a retry.Webhooks — the delivery log for a single attempt.
Returns the delivery log for a single webhook attempt — what was sent, the response your endpoint returned, how many attempts were made, and how long it took. Look it up by the X-Webhook-Delivery-Id header value received on the webhook call, so store that header when handling webhooks. Only deliveries belonging to your own tenant are visible.
| Field | Type | Required | Description |
|---|---|---|---|
delivery_id | string (max 100) | Required | Value of the X-Webhook-Delivery-Id header from the webhook call. |
{
"delivery_id": "bd142d9e-31f6-459f-b8d8-5c5cb902fbd9"
}{
"status": 200,
"message": "Delivery fetched successfully",
"data": {
"envelop_id": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc",
"id": 4821,
"webhook_config_id": 17,
"delivery_id": "bd142d9e-31f6-459f-b8d8-5c5cb902fbd9",
"event_type": "document.completed",
"request_payload": "{\"event\":\"document.completed\",\"data\":{...}}",
"response_status": 200,
"status": "success",
"response_body": "{\"received\":true}",
"error_message": null,
"attempt_count": 1,
"duration_ms": 214,
"delivered_at": "2026-08-03 10:24:12",
"created_at": "2026-08-03T10:24:11.000000Z",
"updated_at": "2026-08-03T10:24:12.000000Z",
"webhook_config": {
"id": 17,
"tenant_id": "acme",
"name": "CRM completion hook",
"url": "https://crm.example.com/hooks/mocha-signature"
}
}
}| Status | Meaning |
|---|---|
| 200 | Delivery log entry. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 404 | No delivery with that id exists for your tenant. |
| 422 | Validation failed. |
| 500 | Unexpected failure. |
| 503 | Authentication dependency unreachable. |
Additional — surface the signing step inside your own UI.
Returns the per-recipient signing URLs for an envelope, so you can surface the signing step inside your own UI instead of relying on the emailed link.
| Field | Type | Required | Description |
|---|---|---|---|
envelop_id | string | Required | The envelope to read signing links for. |
{
"envelop_id": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc"
}{
"status": true,
"status_code": 200,
"msg": "Signing links fetched successfully",
"data": [
{
"contact_id": 3312,
"email": "john.doe@example.com",
"signing_url": "https://app.uat.mochatechnologies.com/mochasignature/sign/...",
"signing_order": 1,
"status": "pending"
}
]
}| Field | Notes |
|---|---|
signing_order | 0 means all recipients sign simultaneously; 1, 2, … means sequential. |
status | One of pending, completed, rejected, approved, acknowledged, declined, unknown. |
| Status | Meaning |
|---|---|
| 200 | Signing links for the envelope's active recipients. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 404 | No active recipients found for the envelope. |
| 422 | Validation failed. |
| 500 | Unexpected failure. |
Additional — the same listing keyed on document_id.
Same listing as Get Templates By User ID, keyed on the template's document_id instead of the user. Returns raw template rows — no pdf_preview is generated.
| Field | Type | Required | Description |
|---|---|---|---|
document_code | string | Required | The template's document_id. |
{
"document_code": "1002022"
}| Status | Meaning |
|---|---|
| 200 | Matching templates. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 422 | Validation failed. |
| 500 | Unexpected failure. |
Additional — repair or extend an envelope assembled another way.
| Field | Type | Required | Description |
|---|---|---|---|
template_id | string | Required | Template whose field definitions are copied. |
envelop_id | string | Required | Envelope the fields are inserted onto. |
recipient_contact_ids | integer[] | Required | Contact ids, in the template's recipient-role order. |
{
"template_id": "73766101002022",
"envelop_id": "b5db5fe9-8a44-4ecc-b3f4-222b14b1d5dc",
"recipient_contact_ids": [3312, 3313]
}{
"status": true,
"message": "Envelope fields inserted successfully",
"data": {
"insertedRows": 12
}
}| Status | Meaning |
|---|---|
| 201 | Fields inserted. |
| 400 | Insert failed. |
| 401 | Api-Key missing, revoked, or not owned by X-Tenant. |
| 422 | Validation failed. |
| 500 | Unexpected failure. |
The objects returned inside data.
| Field | Type | Description |
|---|---|---|
template_id | string | Template identifier — send this to Send Envelope. |
user_id | string | Template owner's user identifier. |
document_id | string | Underlying document code. |
title | string | Template title. |
description | string | null | Template description. |
total_pages | integer | null | Page count of the template PDF. |
user_name | string | Template owner's first name. |
email | string (email) | Template owner's email. |
job | string | null | Owner's job title. |
industry | string | null | Owner's industry. |
pdf_path | string | Storage key of the template PDF. |
pdf_preview | string | null | Pre-signed URL to the template PDF, valid for 10 minutes. null when the object is not present in storage. |
| Field | Type | Description |
|---|---|---|
template_id | string | Template identifier. |
title | string | Template title. |
discription | string | null | Template description. The misspelling is intentional — it is the wire field name. |
status | integer | Template state flag. |
required_recipient | integer | Number of recipients the template expects. Send Envelope requires exactly this many entries in recipients_role. |
recipients_role | string[] | The recipient role titles defined on the template. Every role you send must be one of these. |
| Field | Type | Description |
|---|---|---|
envelope_id | string | The envelope being tracked. |
mail_status | string | Whether the signing invitation was dispatched: Email Sent or Email Failed. |
envelope_completion_status | string | Overall envelope state: Pending, Completed, Rejected or N/A. Rejected means a recipient declined. |
recipients | TrackedRecipient[] | Recipients in signing order. |
| Field | Type | Description |
|---|---|---|
recipient_name | string | null | Recipient's name. |
recipient_email | string | null | Recipient's email. |
status | string | Pending Signature, Completed, Declined or N/A. |
decline_reason | string | null | The recipient's stated reason. Non-null only when status is Declined. |
viewed_at | string | null | When the recipient first opened the document. null if never opened. |
completed_at | string | null | When the recipient finished their action. |
| Field | Type | Description |
|---|---|---|
event | string | document.completed or document.declined. |
data | WebhookDocumentData | Event payload. |
timestamp | string (date-time) | ISO-8601 time the payload was built. |
| Field | Type | Description |
|---|---|---|
user_id | string | Owner of the envelope — the sending account. |
envelop_id | string | Matches the envelope_id returned by Send Envelope. |
status | string | completed or declined. |
generated_at | string (date-time) | When the event was generated. |
metadata | object | null | The metadata supplied on Send Envelope, returned verbatim. |
document.file_name | string | null | File name of the signed PDF. |
document.download_url | string | null | Pre-signed URL to the signed PDF, valid for 15 minutes. Download the file on receipt; do not store the URL. null if the link could not be generated. |
document.mime_type | string | Always application/pdf. |
| Field | Type | Description |
|---|---|---|
delivery_id | string (uuid) | The delivery you looked up. |
envelop_id | string | null | Extracted from the delivered payload for convenience. |
id | integer | Internal delivery row id. |
webhook_config_id | integer | Configuration this delivery belongs to. |
event_type | string | Event that triggered the delivery. |
request_payload | string | The exact JSON string that was signed and sent. Signatures are computed over this. |
response_status | integer | null | HTTP status your endpoint returned. null if the request never completed. |
status | string | pending, success or failed. |
response_body | string | null | Body your endpoint returned. |
error_message | string | null | Transport-level failure detail, e.g. connection timeout. |
attempt_count | integer | Attempts made so far — up to 4, backing off 60s / 5m / 15m / 30m. |
duration_ms | integer | null | Round-trip time of the attempt. |
delivered_at | string | null | When the delivery succeeded. |
webhook_config | object | id, tenant_id, name and url of the configuration. |
Every status code the API returns, and the body that comes with it.
| Status | Meaning |
|---|---|
| 200 | Success. Read the payload from data. |
| 201 | Created — Insert Envelope Template Fields only. |
| 204 | No template maps to the supplied template_id. No body is transmitted. |
| 400 | Insert failed — Insert Envelope Template Fields only. |
| 401 | The Api-Key header is missing, revoked, or does not belong to the tenant in X-Tenant. Also returned if the platform could not issue an internal token for the key's user. |
| 404 | The tenant in X-Tenant does not exist, the key's user has no email on record, or the requested envelope / delivery was not found. |
| 422 | Request body failed validation. msg holds a field → messages map. |
| 500 | Unexpected failure while processing the request. error carries the reason. |
| 503 | A dependency needed to authenticate the request was unreachable. Safe to retry after a short backoff. |
| Shape | Returned by | Fields |
|---|---|---|
| ValidationErrorBody | 422 | status (false), msg — field name → list of messages. |
| ServerErrorBody | 500 | status (false), message, error, status_code. |
| MessageBody | 401, 404, 503 | message — e.g. Invalid API Key, Tenant 'acme' not found., Central service unavailable. |
503 and transport failures with exponential backoff — the request was not processed. Never retry a 422; it will fail identically until the payload is fixed.