Official Python SDK for DocWal API - Issue and manage verifiable digital credentials.
pip install docwalfrom docwal import DocWalClient
# Initialize client with your API key
client = DocWalClient(api_key="docwal_live_xxxxx")
# Issue a credential
result = client.credentials.issue(
template_id="template-123",
individual_email="student@example.com",
credential_data={
"student_name": "John Doe",
"degree": "Bachelor of Science",
"major": "Computer Science",
"graduation_date": "2024-05-15",
"gpa": "3.8"
}
)
print(f"Credential issued! Doc ID: {result['doc_id']}")
print(f"Claim token: {result['claim_token']}")Get your API key from your DocWal dashboard:
- Login to https://docwal.com
- Navigate to Settings → API Keys
- Click "Generate API Key"
- Copy and store securely
Requirements:
- Pilot tier or above
- Owner or Admin role
# Production (default)
client = DocWalClient(api_key="docwal_live_xxxxx")
# Staging
client = DocWalClient(
api_key="docwal_test_xxxxx",
base_url="https://sandbox.docwal.com/api"
)
# Custom timeout
client = DocWalClient(
api_key="docwal_live_xxxxx",
timeout=60 # seconds
)# Basic credential
result = client.credentials.issue(
template_id="template-123",
individual_email="student@example.com",
credential_data={
"student_name": "John Doe",
"degree": "Bachelor of Science",
"graduation_date": "2024-05-15"
}
)
# With PDF attachment
with open("certificate.pdf", "rb") as f:
result = client.credentials.issue(
template_id="template-123",
individual_email="student@example.com",
credential_data={"student_name": "John Doe"},
document_file=f,
claim_token_expires_hours=168 # 7 days
)credentials_list = [
{
"individual_email": "student1@example.com",
"credential_data": {
"student_name": "Alice Smith",
"degree": "Bachelor of Arts",
"graduation_date": "2024-05-15"
}
},
{
"individual_email": "student2@example.com",
"credential_data": {
"student_name": "Bob Johnson",
"degree": "Bachelor of Science",
"graduation_date": "2024-05-15"
}
}
]
result = client.credentials.batch_issue(
template_id="template-123",
credentials=credentials_list,
send_notifications=True
)
print(f"Success: {result['success_count']}/{result['total_rows']}")# ZIP structure:
# batch_credentials.zip
# ├── credentials.csv
# └── documents/
# ├── student001.pdf
# ├── student002.pdf
# └── student003.pdf
with open("batch_credentials.zip", "rb") as f:
result = client.credentials.batch_upload(
template_id="template-123",
file=f,
send_notifications=True
)
print(f"Processed: {result['total_rows']}")
print(f"Success: {result['success_count']}")
print(f"Failed: {result['failure_count']}")
for item in result['results']:
if item['status'] == 'success':
print(f"Row {item['row']}: {item['doc_id']}")
else:
print(f"Row {item['row']}: {item['error']}")# List all credentials
credentials = client.credentials.list(limit=50, offset=0)
for cred in credentials:
print(f"{cred['doc_id']}: {cred['template_name']}")
# Get specific credential
credential = client.credentials.get("DOC123456")
print(f"Issued to: {credential['ownership']['individual_email']}")
print(f"Status: {'Claimed' if credential['ownership']['is_claimed'] else 'Pending'}")result = client.credentials.revoke(
doc_id="DOC123456",
reason="Student expelled for academic misconduct"
)
print(result['message'])result = client.credentials.resend_claim_link(
doc_id="DOC123456",
claim_token_expires_hours=168 # 7 days
)
print(f"Sent to: {result['recipient_email']}")
print(f"Expires: {result['claim_token_expires']}")# Download PDF file
pdf_content = client.credentials.download("DOC123456")
with open("credential.pdf", "wb") as f:
f.write(pdf_content)# List templates
templates = client.templates.list()
# Get template
template = client.templates.get("template-123")
# Create template
template = client.templates.create(
name="Bachelor Degree Certificate",
description="Template for bachelor degree graduation certificates",
credential_type="certificate",
schema={
"student_name": {
"type": "string",
"required": True,
"label": "Student Name"
},
"degree": {
"type": "string",
"required": True,
"label": "Degree Program"
},
"graduation_date": {
"type": "date",
"required": True,
"label": "Graduation Date"
}
},
version="1.0"
)
# Update template
client.templates.update(
"template-123",
description="Updated description"
)
# Delete template (soft delete)
client.templates.delete("template-123")# Generate new API key (Owner/Admin only)
result = client.api_keys.generate()
print(f"New API key: {result['api_key']}")
print("⚠️ Store securely - shown only once!")
# Get API key info
info = client.api_keys.info()
print(f"Masked key: {info['api_key_masked']}")
print(f"Created: {info['created_at']}")
print(f"Last used: {info['last_used_at']}")
# Regenerate API key
result = client.api_keys.regenerate()
print(f"New API key: {result['api_key']}")
# Revoke API key
client.api_keys.revoke()# List team members
team = client.team.list()
print(f"Active members: {team['stats']['active_members']}")
print(f"Pending invitations: {team['stats']['pending_invitations']}")
# Check email before inviting
check = client.team.check_email("newmember@university.edu")
if check['recommendation'] == 'add_directly':
print("User exists - can add directly")
elif check['recommendation'] == 'send_invitation':
print("User doesn't exist - must send invitation")
# Invite team member
result = client.team.invite(
email="newmember@university.edu",
role="issuer",
send_email=True
)
# Update member role
client.team.update_role(
member_id="member-123",
role="admin"
)
# Deactivate member
client.team.deactivate(
member_id="member-123",
reason="Employee on leave"
)
# Reactivate member
client.team.reactivate("member-123")
# Remove member permanently
client.team.remove("member-123")from docwal import DocWalClient, DocWalError, AuthenticationError, ValidationError
client = DocWalClient(api_key="docwal_live_xxxxx")
try:
result = client.credentials.issue(
template_id="invalid-template",
individual_email="student@example.com",
credential_data={}
)
except AuthenticationError as e:
print(f"Authentication failed: {e}")
print("Check your API key")
except ValidationError as e:
print(f"Validation error: {e}")
print("Check required fields")
except DocWalError as e:
print(f"API error: {e}")
print(f"Status code: {e.status_code}")- Pilot: 500 requests/hour
- Standard: 1,000 requests/hour
- Enterprise: Unlimited
When rate limit is exceeded, RateLimitError is raised.
- Email: support@docwal.com
- Documentation: https://docs.docwal.com
- API Reference: https://docwal.com/api/docs
- GitHub: https://github.com/docwal/docwal-python
MIT License - see LICENSE file for details.