Documentation
POST /jobs/seal — create a sealing job
Illustrative multipart request, webhook hints, blocking mode, and partial failure taxonomy.
POST /v1/jobs/seal ingests binaries or source_url references, records metadata, hashes offloaded storage, wraps digests inside our multi-region KMS, and persists tamper-evident manifests.
Request shaping
| Mode | Behaviour |
|---|---|
**blocking / sync (recommended) | Keeps TLS open until sign + TSA complete — ~300ms in signing tests for typical PDFs. Default production path per architecture docs. |
async | Returns HTTP 202 with queued phase; poll /jobs/:id or webhooks. No queue fleet required — compat for clients that won’t hold the connection open. |
Multipart illustration
Sample fields we expect when not streaming presigned uploads:
file=@contract.pdf # XOR with source_url
visibility=organization # enumeration: private | organization | partner
purpose=financial_close # free-form label for quotas + analytics
preserve_metadata=false # optional; strips XMP chunks when true compliance mode on
customer_reference=acct_982 # echoes back on receipts/webhooks verbatim JSON alternative (premium preview)
Partners that already store documents in hardened buckets prefer referencing URLs:
{
"source_url": "https://downloads.example.net/hr/policy.pdf",
"checksum_sha256": "E3B0C44298FC…",
"visibility": "organization",
"mode": "blocking"
} We perform defensive HEAD probes and reject mismatched fingerprints before accepting the job—prevents spoofing workloads.
Response excerpt
{
"id": "job_014b7c",
"phase": "completed",
"environment": "env_sandbox_01",
"trace_id": "4f6d2c8eafbd",
"capabilities": ["receipt.sha512", "webhook.job.completed"]
} Multi-language examples
The endpoint accepts either multipart/form-data uploads or JSON bodies that reference an
already-hosted PDF.
curl https://api.sandbox.seal.club/v1/jobs/seal
-H "Authorization: Bearer $SEAL_TOKEN"
-H "Idempotency-Key: contract-2026-05-08"
-F file=@contract.pdf
-F visibility=organization
-F purpose=financial_close const response = await fetch('https://api.sandbox.seal.club/v1/jobs/seal', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SEAL_TOKEN}`,
'Idempotency-Key': 'contract-2026-05-08',
'Content-Type': 'application/json',
},
body: JSON.stringify({
source_url: 'https://downloads.example.net/contracts/close.pdf',
checksum_sha256: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855',
visibility: 'organization',
purpose: 'financial_close',
mode: 'async',
}),
});
console.log(await response.json()); import os
import requests
payload = {
"source_url": "https://downloads.example.net/contracts/close.pdf",
"checksum_sha256": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"visibility": "organization",
"purpose": "financial_close",
"mode": "blocking",
}
response = requests.post(
"https://api.sandbox.seal.club/v1/jobs/seal",
headers={
"Authorization": f"Bearer {os.environ['SEAL_TOKEN']}",
"Idempotency-Key": "contract-2026-05-08",
},
json=payload,
timeout=30,
)
print(response.json()) Partial failures
| Symptom | Meaning |
|---|---|
virus_scan_failed | File never entered hashing; purge client copy. |
checksum_mismatch | Declared fingerprint disagrees with streamed bytes—retry safely with new upload. |
kms_partition_unavailable | Rare multi-region failover; surfaced as 503 retryable. |