Skip to main content

DocWal Python SDK

Official Python SDK for DocWal API - Issue and manage verifiable digital credentials.

Installation

pip install docwal

Quick Start

from 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']}")

Authentication

Get your API key from your DocWal dashboard:

  1. Login to https://docwal.com
  2. Navigate to Settings → API Keys
  3. Click "Generate API Key"
  4. Copy and store securely

Requirements:

  • Pilot tier or above
  • Owner or Admin role

Environment Configuration

# 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
)

Usage Examples

Issue Single Credential

# 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
    )

Batch Issue Credentials

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']}")

Batch Upload with ZIP

# 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 and Get Credentials

# 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'}")

Revoke Credential

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 Credential File

# Download PDF file
pdf_content = client.credentials.download("DOC123456")

with open("credential.pdf", "wb") as f:
    f.write(pdf_content)

Template Management

# 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")

API Key Management

# 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()

Team Management

# 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")

Error Handling

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}")

Rate Limits

  • Pilot: 500 requests/hour
  • Standard: 1,000 requests/hour
  • Enterprise: Unlimited

When rate limit is exceeded, RateLimitError is raised.

Support

License

MIT License - see LICENSE file for details.

Metadata

Release files for docwal 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for docwal 1.0.1
File Size Uploaded Provenance
docwal-1.0.1.tar.gz 11.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for docwal 1.0.1
File Interpreter ABI Platform
docwal-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.6 kB

Release files / docwal-1.0.1.tar.gz

Download URL docwal-1.0.1.tar.gz
Size 11.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8645a604c6dcc92037f6bbbfa0e8da0aca68893ec71138fa3e4ca596d5e51e49
BLAKE2b-256 checksum
How to use checksums
44238e5479ca3271176317fb92bd6c75533795c9633bda31fc4828ef6e00695e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / docwal-1.0.1-py3-none-any.whl

Download URL docwal-1.0.1-py3-none-any.whl
Size 8.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28724e7d1ff264cbb3521b1c8c1380b20b0c8384acf44b1517e31d0c99e6e524
BLAKE2b-256 checksum
How to use checksums
d1788b35c03e1b50ab17c7362c2d40549c33c3b6ef6905ed875c333ae417cba8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for docwal 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page