SignNow
Access the SignNow API with managed OAuth authentication. Upload documents, send signature invites, manage templates, and automate e-signature workflows.
Quick Start
# Get current user info
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/signnow/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/signnow/{resource}
The gateway proxies requests to api.signnow.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your SignNow OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=signnow&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'signnow'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
json
{
"connection": {
"connection_id": "5ff5474b-5f21-41ba-8bf3-afb33cce5a75",
"status": "ACTIVE",
"creation_time": "2026-02-08T20:47:23.019763Z",
"last_updated_time": "2026-02-08T20:50:32.210896Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "signnow",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple SignNow connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/signnow/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '5ff5474b-5f21-41ba-8bf3-afb33cce5a75')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
User Operations
Get Current User
GET /signnow/user
Response:
json
{
"id": "59cce130e93a4e9488522ca67e3a6779f3e48a72",
"first_name": "Chris",
"last_name": "Kim",
"active": "1",
"verified": true,
"emails": ["[email protected]"],
"primary_email": "[email protected]",
"document_count": 0,
"subscriptions": [...],
"teams": [...],
"organization": {...}
}
Get User Documents
GET /signnow/user/documents
Response:
json
[
{
"id": "c63a7bc73f03449c987bf0feaa36e96212408352",
"document_name": "Contract",
"page_count": "3",
"created": "1770598603",
"updated": "1770598603",
"original_filename": "contract.pdf",
"owner": "[email protected]",
"template": false,
"roles": [],
"field_invites": [],
"signatures": []
}
]
Document Operations
Upload Document
Documents must be uploaded as multipart form data with a PDF file:
python <<'EOF'
import urllib.request, os, json
def encode_multipart_formdata(files):
boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
lines = []
for (key, filename, content) in files:
lines.append(f'--{boundary}'.encode())
lines.append(f'Content-Disposition: form-data; name="{key}"; filename="{filename}"'.encode())
lines.append(b'Content-Type: application/pdf')
lines.append(b'')
lines.append(content)
lines.append(f'--{boundary}--'.encode())
lines.append(b'')
body = b'\r\n'.join(lines)
content_type = f'multipart/form-data; boundary={boundary}'
return content_type, body
with open('document.pdf', 'rb') as f:
file_content = f.read()
content_type, body = encode_multipart_formdata([('file', 'document.pdf', file_content)])
req = urllib.request.Request('https://gateway.maton.ai/signnow/document', data=body, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', content_type)
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
json
{
"id": "c63a7bc73f03449c987bf0feaa36e96212408352"
}
Get Document
GET /signnow/document/{document_id}
Response:
json
{
"id": "c63a7bc73f03449c987bf0feaa36e96212408352",
"document_name": "Contract",
"page_count": "3",
"created": "1770598603",
"updated": "1770598603",
"original_filename": "contract.pdf",
"owner": "[email protected]",
"template": false,
"roles": [],
"viewer_roles": [],
"attachments": [],
"fields": [],
"signatures": [],
"texts": [],
"checks": []
}
Update Document
PUT /signnow/document/{document_id}
Content-Type: application/json
{
"document_name": "Updated Contract Name"
}
Response:
json
{
"id": "c63a7bc73f03449c987bf0feaa36e96212408352",
"signatures": [],
"texts": [],
"checks": []
}
Download Document
GET /signnow/document/{document_id}/download?type=collapsed
Returns the PDF file as binary data.
Query parameters:
- type - Download type: collapsed (flattened PDF), zip (all pages as images)
Get Document History
GET /signnow/document/{document_id}/historyfull
Response:
json
[
{
"unique_id": "c4eb89d84b2b407ba8ec1cf4d25b8b435bcef69d",
"user_id": "59cce130e93a4e9488522ca67e3a6779f3e48a72",
"document_id": "c63a7bc73f03449c987bf0feaa36e96212408352",
"email": "[email protected]",
"created": 1770598603,
"event": "created_document"
}
]
Move Document to Folder
POST /signnow/document/{document_id}/move
Content-Type: application/json
{
"folder_id": "5e2798bdd3d642c3aefebe333bb5b723d6db01a4"
}
Response:
json
{
"result": "success"
}
Merge Documents
Combines multiple documents into a single PDF:
POST /signnow/document/merge
Content-Type: application/json
{
"name": "Merged Document",
"document_ids": ["doc_id_1", "doc_id_2"]
}
Returns the merged PDF as binary data.
Delete Document
DELETE /signnow/document/{document_id}
Response:
json
{
"status": "success"
}
Template Operations
Create Template from Document
POST /signnow/template
Content-Type: application/json
{
"document_id": "c63a7bc73f03449c987bf0feaa36e96212408352",
"document_name": "Contract Template"
}
Response:
json
{
"id": "47941baee4f74784bc1d37c25e88836fc38ed501"
}
Create Document from Template
POST /signnow/template/{template_id}/copy
Content-Type: application/json
{
"document_name": "New Contract from Template"
}
Response:
json
{
"id": "08f5f4a2cc1a4d6c8a986adbf90be2308807d4ae",
"name": "New Contract from Template"
}
Signature Invite Operations
Send Freeform Invite
Send a document for signature:
POST /signnow/document/{document_id}/invite
Content-Type: application/json
{
"to": "[email protected]",
"from": "[email protected]"
}
Response:
json
{
"result": "success",
"id": "c38a57f08f2e48d98b5de52f75f7b1dd0a074c00",
"callback_url": "none"
}
Note: Custom subject and message require a paid subscription plan.
Create Signing Link
Create an embeddable signing link (requires document fields):
POST /signnow/link
Content-Type: application/json
{
"document_id": "c63a7bc73f03449c987bf0feaa36e96212408352"
}
Note: Document must have signature fields added before creating a signing link.
Folder Operations
Get All Folders
GET /signnow/folder
Response:
json
{
"id": "2ea71a3a9d06470d8e5ec0df6122971f47db7706",
"name": "Root",
"system_folder": true,
"folders": [
{
"id": "5e2798bdd3d642c3aefebe333bb5b723d6db01a4",
"name": "Documents",
"document_count": "5",
"template_count": "2"
},
{
"id": "fafdef6de6d947fc84627e4ddeed6987bfeee02d",
"name": "Templates",
"document_count": "0",
"template_count": "3"
},
{
"id": "6063688b1e724a25aa98befcc3f2cb7795be7da1",
"name": "Trash Bin",
"document_count": "0"
}
],
"total_documents": 0,
"documents": []
}
Get Folder by ID
GET /signnow/folder/{folder_id}
Response:
json
{
"id": "5e2798bdd3d642c3aefebe333bb5b723d6db01a4",
"name": "Documents",
"user_id": "59cce130e93a4e9488522ca67e3a6779f3e48a72",
"parent_id": "2ea71a3a9d06470d8e5ec0df6122971f47db7706",
"system_folder": true,
"folders": [],
"total_documents": 5,
"documents": [...]
}
Webhook (Event Subscription) Operations
List Event Subscriptions
GET /signnow/event_subscription
Response:
json
{
"subscriptions": [
{
"id": "b1d6700dfb0444ed9196e913b2515ae8d5f731a7",
"event": "document.complete",
"created": "1770598678",
"callback_url": "https://example.com/webhook"
}
]
}
Create Event Subscription
POST /signnow/event_subscription
Content-Type: application/json
{
"event": "document.complete",
"callback_url": "https://example.com/webhook"
}
Response:
json
{
"id": "b1d6700dfb0444ed9196e913b2515ae8d5f731a7",
"created": 1770598678
}
Available Events:
- document.create - Document created
- document.update - Document updated
- document.delete - Document deleted
- document.complete - Document signed by all parties
- invite.create - Invite sent
- invite.update - Invite updated
Delete Event Subscription
DELETE /signnow/event_subscription/{subscription_id}
Response:
json
{
"id": "b1d6700dfb0444ed9196e913b2515ae8d5f731a7",
"status": "deleted"
}
Code Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/signnow/user',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/signnow/user',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
Python (Upload Document)
import os
import requests
with open('document.pdf', 'rb') as f:
response = requests.post(
'https://gateway.maton.ai/signnow/document',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
files={'file': ('document.pdf', f, 'application/pdf')}
)
doc = response.json()
print(f"Uploaded document: {doc['id']}")
Python (Send Invite)
import os
import requests
doc_id = "c63a7bc73f03449c987bf0feaa36e96212408352"
response = requests.post(
f'https://gateway.maton.ai/signnow/document/{doc_id}/invite',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'to': '[email protected]',
'from': '[email protected]'
}
)
result = response.json()
print(f"Invite sent: {result['id']}")
Notes
- Documents must be in PDF format for upload
- Supported file types: PDF, DOC, DOCX, ODT, RTF, PNG, JPG
- System folders (Documents, Templates, Archive, Trash Bin) cannot be renamed or deleted
- Creating signing links requires documents to have signature fields
- Custom invite subject/message requires a paid subscription
- Rate limit in development mode: 500 requests/hour per application
- IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing SignNow connection or bad request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions or subscription required |
| 404 | Resource not found |
| 405 | Method not allowed |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from SignNow API |
SignNow errors include detailed messages:
json
{
"errors": [
{
"code": 65578,
"message": "Invalid file type."
}
]
}
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
signnow. For example:
- Correct:
https://gateway.maton.ai/signnow/user - Incorrect:
https://gateway.maton.ai/user