Skip to content

The Documents API allows you to manage documents in your WPsigner installation. You can create new documents, retrieve their details, update metadata, and delete them.

Retrieve a paginated list of all documents.

GET /wp-json/insigner/v1/documents
ParameterTypeDefaultDescription
pageinteger1Page number for pagination
per_pageinteger20Number of documents per page (max: 100)
statusstring-Filter by status: draft, sent, viewed, completed, declined, expired
searchstring-Search documents by title
Terminal window
curl -X GET "https://your-site.com/wp-json/insigner/v1/documents?per_page=10&status=completed" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret"
[
{
"id": "44",
"title": "Employment Contract",
"status": "completed",
"original_filename": "contract.pdf",
"total_pages": "5",
"expires_at": "2024-03-15 12:00:00",
"completed_at": "2024-01-20 15:30:45",
"created_at": "2024-01-15 10:00:00",
"updated_at": "2024-01-20 15:30:45"
},
{
"id": "43",
"title": "NDA Agreement",
"status": "sent",
"original_filename": "nda.pdf",
"total_pages": "3",
"expires_at": "2024-02-28 23:59:59",
"completed_at": null,
"created_at": "2024-01-14 09:00:00",
"updated_at": "2024-01-14 09:15:00"
}
]
HeaderDescription
X-WP-TotalTotal number of documents
X-WP-TotalPagesTotal number of pages

Retrieve a single document with full details, including signers and fields.

GET /wp-json/insigner/v1/documents/{id}
ParameterTypeDescription
idintegerRequired. Document ID
Terminal window
curl -X GET "https://your-site.com/wp-json/insigner/v1/documents/44" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret"
{
"id": "44",
"title": "Employment Contract",
"status": "completed",
"original_filename": "contract.pdf",
"total_pages": "5",
"expires_at": "2024-03-15 12:00:00",
"completed_at": "2024-01-20 15:30:45",
"created_at": "2024-01-15 10:00:00",
"updated_at": "2024-01-20 15:30:45",
"file_hash": "8228aa40168a599d2296e1274eb9dc9d7982d93e40135b8ed9131f1b4e2de5f8",
"signers": [
{
"id": "38",
"document_id": "44",
"name": "John Doe",
"email": "john@example.com",
"role": "signer",
"signing_order": "1",
"status": "signed",
"viewed_at": "2024-01-20 14:00:00",
"signed_at": "2024-01-20 15:30:45",
"declined_at": null,
"decline_reason": null,
"created_at": "2024-01-15 10:05:00",
"updated_at": "2024-01-20 15:30:45"
}
],
"fields": [
{
"id": "74",
"document_id": "44",
"signer_id": "38",
"field_type": "signature",
"page_number": "5",
"position_x": "90.0",
"position_y": "276.9",
"width": "200",
"height": "60",
"is_required": "1"
}
]
}
StatusDescription
draftDocument created but not sent
sentSent to signers, awaiting action
viewedAt least one signer has viewed
completedAll signers have signed
declinedA signer declined to sign
expiredDocument has expired

Upload a PDF (or PNG/JPG) and create a document in one request.

POST /wp-json/insigner/v1/documents/upload

Note: Requires Full Access. Send multipart/form-data.

FieldTypeRequiredDescription
filefileYesPDF, PNG, or JPG (document is also accepted)
titlestringNoDefaults to the filename stem
Terminal window
curl -X POST "https://your-site.com/wp-json/insigner/v1/documents/upload" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret" \
-F "file=@/path/to/contract.pdf" \
-F "title=New Contract"
{
"id": "45",
"title": "New Contract",
"status": "draft",
"original_filename": "New Contract.pdf",
"total_pages": "3",
"expires_at": null,
"completed_at": null,
"created_at": "2024-01-25 10:00:00",
"updated_at": "2024-01-25 10:00:00"
}

Create a document from an already-stored secure file path. Prefer /documents/upload for normal integrations.

POST /wp-json/insigner/v1/documents

Note: Requires Full Access. file_path must be inside WPsigner secure storage and freshly uploaded (≤ 15 minutes).

ParameterTypeRequiredDescription
titlestringYesDocument title
file_pathstringNoAbsolute path inside secure storage
original_filenamestringNoOriginal filename
Terminal window
curl -X POST "https://your-site.com/wp-json/insigner/v1/documents" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret" \
-H "Content-Type: application/json" \
-d '{
"title": "New Contract",
"file_path": "/var/www/html/wp-content/uploads/wpsigner-secure/documents/abc123.pdf.enc",
"original_filename": "contract.pdf"
}'
{
"id": "45",
"title": "New Contract",
"status": "draft",
"original_filename": "New Contract.pdf",
"total_pages": "1",
"expires_at": null,
"completed_at": null,
"created_at": "2024-01-25 10:00:00",
"updated_at": "2024-01-25 10:00:00"
}

Update a document’s title or status.

PUT /wp-json/insigner/v1/documents/{id}

Note: This endpoint requires Full Access permission.

ParameterTypeDescription
idintegerRequired. Document ID
ParameterTypeDescription
titlestringNew document title
statusstringNew status
Terminal window
curl -X PUT "https://your-site.com/wp-json/insigner/v1/documents/45" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Contract Title"
}'

Returns the updated document object.


Permanently delete a document and all associated data.

DELETE /wp-json/insigner/v1/documents/{id}

Note: This endpoint requires Full Access permission.

Warning: This action cannot be undone. All signers, fields, and audit records will be deleted.

ParameterTypeDescription
idintegerRequired. Document ID
Terminal window
curl -X DELETE "https://your-site.com/wp-json/insigner/v1/documents/45" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret"
{
"deleted": true
}

Send a document to all signers for signing. This will email signing invitations.

POST /wp-json/insigner/v1/documents/{id}/send

Note: This endpoint requires Full Access permission.

Before sending, ensure:

  • At least one signer is added to the document
  • All required fields are placed on the document
ParameterTypeDescription
idintegerRequired. Document ID
Terminal window
curl -X POST "https://your-site.com/wp-json/insigner/v1/documents/44/send" \
-H "X-WPS-API-Key: wps_your_key" \
-H "X-WPS-API-Secret: your_secret"
{
"sent": true,
"message": "Document sent successfully."
}
{
"code": "no_signers",
"message": "Please add at least one signer.",
"data": {
"status": 400
}
}

Download the document PDF as base64-encoded JSON (secure storage paths are never exposed as public URLs).

GET /wp-json/insigner/v1/documents/{id}/file
{
"content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago...",
"filename": "contract.pdf",
"type": "application/pdf",
"encoding": "base64"
}

Send reminder email(s) to pending or viewed signers.

POST /wp-json/insigner/v1/documents/{id}/remind

This endpoint requires Full Access. Without a body, WPsigner reminds every eligible signer. To target one signer, send:

{
"signer_id": 38
}
{
"reminded": [38],
"failed": [],
"message": "Reminder sent to 1 signer."
}

WPsigner returns 400 no_recipients when there are no eligible pending or viewed signers.


Mark a document as expired only when its configured expires_at date is already in the past.

POST /wp-json/insigner/v1/documents/{id}/expire

This endpoint requires Full Access. It does not force-expire an active document before its due date and cannot change a document already in a terminal state.

{
"expired": true,
"document": {
"id": "44",
"status": "expired"
}
}

WPsigner returns 400 not_due if expires_at is empty or still in the future.


Retrieve the complete audit trail for a document.

GET /wp-json/insigner/v1/documents/{id}/audit
{
"document": {
"id": "44",
"title": "Employment Contract",
"file_hash": "8228aa40168a599d..."
},
"events": [
{
"action": "document_created",
"timestamp": "2024-01-15 10:00:00",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0..."
},
{
"action": "document_viewed",
"timestamp": "2024-01-20 14:00:00",
"signer": "John Doe",
"ip_address": "203.0.113.50"
},
{
"action": "document_signed",
"timestamp": "2024-01-20 15:30:45",
"signer": "John Doe",
"ip_address": "203.0.113.50"
}
]
}

{
"code": "not_found",
"message": "Document not found.",
"data": {
"status": 404
}
}

When trying to access a document you don’t own (non-admin users):

{
"code": "forbidden",
"message": "Permission denied.",
"data": {
"status": 403
}
}