A Swift client for the DocuSeal API built with AsyncHTTPClient for seamless electronic signature and document management.
- Linux
- macOS 14.0+
- Swift 6+
Add the following to your Package.swift file's dependencies:
dependencies: [
.package(url: "https://github.com/thoven87/docuseal-kit.git", from: "2.0.0")
]Then in your target dependencies:
targets: [
.target(
name: "YourTarget",
dependencies: ["DocuSealKit"]),
]import DocuSealKit
let client = DocuSealClient(apiKey: "your-api-key")API keys for the EU cloud can be obtained from your EU DocuSeal Console.
import DocuSealKit
let client = DocuSealClient(
baseURL: "https://api.docuseal.eu"
apiKey: "your-api-key",
)For on-premises installations, API keys can be retrieved from the API settings page of your deployed application, e.g., https://yourdocusealapp.com/settings/api.
import DocuSealKit
let client = DocuSealClient(
baseURL: "https://yourdocusealapp.com/api"
apiKey: "your-api-key",
)let templates = try await client.listTemplates()
print("Found \(templates.data.count) templates")let request = CreateTemplateFromPdfRequest(
name: "Employment Contract",
documents: [
TemplateDocumentRequest(
name: "Contract",
file: "base64-encoded-pdf-content",
fields: [
TemplateFieldRequest(
name: "Signature",
type: "signature",
role: "Employee",
required: true,
areas: [
TemplateFieldAreaRequest(
x: 0.7,
y: 0.9,
w: 0.25,
h: 0.05,
page: 2
)
]
)
]
)
]
)
let template = try await client.createTemplateFromPdf(request: request)
print("Created template: \(template.id)")let request = CreateTemplateFromHtmlRequest(
html: "<p>This agreement between <text-field name='Company' role='Company'></text-field> and <text-field name='Customer' role='Customer'></text-field>...</p>",
name: "Service Agreement"
)
let template = try await client.createTemplateFromHtml(request: request)
print("Created template: \(template.id)")let submissionRequest = CreateSubmissionRequest(
templateId: 1000001,
submitters: [
SubmissionSubmitter(
role: "First Party",
email: "[email protected]"
)
]
)
let submitters = try await client.createSubmission(request: submissionRequest)
print("Created submission for \(submitters.count) submitters")// In your webhook handler
func handleDocuSealWebhook(requestBody: ByteBuffer) async throws {
// Parse webhook event once - returns categorized event with parsed data
let eventCategory = try DocusealWebhookHandler.parseWebhookEvent(from: requestBody)
// Process based on event category
switch eventCategory {
case .formEvent(let event):
print("Form event: \(event.eventType.rawValue)")
print("Form completed: \(event.data.id)")
// Download documents
if let documents = event.data.documents {
for document in documents {
// Download document from document.url
}
}
case .submissionEvent(let event):
print("Submission event: \(event.eventType.rawValue)")
print("Submission created: \(event.data.id)")
// Access strongly-typed submission data
if let status = event.data.status {
print("Status: \(status)")
}
case .templateEvent(let event):
print("Template event: \(event.eventType.rawValue)")
print("Template updated: \(event.data.id)")
// Access template-specific data
print("Template name: \(event.data.name)")
}
}The client supports the following DocuSeal API endpoints:
- List all templates
- Get a template
- Create a template from Word DOCX
- Create a template from HTML
- Create a template from PDF
- Merge templates
- Clone a template
- Update a template
- Update template documents
- Archive a template
- List all submissions
- Get a submission
- Get submission documents
- Create a submission
- Create submissions from emails
- Archive a submission
- List all submitters
- Get a submitter
- Update a submitter
DocuSeal Kit supports three types of webhook events with full type safety:
Form Events:
form.viewed- Form was viewed by a submitterform.started- Form submission was startedform.completed- Form was completed by a submitterform.declined- Form was declined by a submitter
Submission Events:
submission.created- New submission was createdsubmission.archived- Submission was archivedsubmission.completed- All submitters completed the submissionsubmission.expired- Submission expired
Template Events:
template.created- New template was createdtemplate.updated- Template was updated
DocuSeal uses key-value pairs in request headers for webhook authentication. Configure this in DocuSeal Console > Webhooks > Add Secret.
// Verify webhook authenticity - throws DocuSealError.webhookAuthenticationError if invalid
try DocusealWebhookHandler.verifyWebhookSecret(
receivedKey: request.headers["X-Secret-Value"]?.first ?? "",
expectedKey: "your-secret-value"
)The parseWebhookEvent method performs single JSON decode and returns strongly-typed events:
let eventCategory = try DocusealWebhookHandler.parseWebhookEvent(from: requestBody)
switch eventCategory {
case .submissionEvent(let event):
// event.eventType guaranteed to be submission-only:
// .submissionCreated, .submissionArchived, .submissionCompleted, .submissionExpired
print("Submission \(event.data.id) - \(event.eventType.rawValue)")
case .formEvent(let event):
// event.eventType guaranteed to be form-only:
// .formViewed, .formStarted, .formCompleted, .formDeclined
print("Form event: \(event.eventType.rawValue)")
case .templateEvent(let event):
// event.eventType guaranteed to be template-only:
// .templateCreated, .templateUpdated
print("Template \(event.data.name) - \(event.eventType.rawValue)")
}MIT