Contents

Documents

The documents as sent, the signed copies and the certificate of signing.

The SigDocument object

Attributes

  • id required Type: string
  • name required Type: string
  • content_type required Type: string
  • bytes required Type: integer
  • sha256 required Type: string
  • pages optional Type: integer null
  • fields optional Type: "found" "reading" "none" "given"

    found: we placed its fields; reading: a scan we are still reading; none: we found no places; given: you placed them. An open set.

  • signed optional Type: object null

    The signed copy, once everyone has signed and it's ready.

SigDocument on its own page

The SigCertificate object

Attributes

  • bytes required Type: integer
  • sha256 required Type: string
  • time_stamped_at optional Type: string null

    When a time-stamp authority dated the seal.

  • check_code optional Type: string null

    The code anyone can enter at unforged.ai/v to check the certificate.

SigCertificate on its own page

Download a document

GET /sig/packages/{package_id}/documents/{document_id}/content

Needs sig:packages:read: See packages, their signers and signed files

The document as it was sent.

Parameters

  • package_id pathrequired Type: string

    The package's id.

  • document_id pathrequired Type: string

    The document's id.

Returns

  • 200
    The document
  • 400 Type: Problem
    invalid_request, invalid_version, idempotency_key_required or invalid_signature
  • 401 Type: Problem
    unauthorized
  • 403 Type: Problem
    permission_denied, org_suspended, or address_not_allowed (your organisation only accepts requests from the addresses it has listed)
  • 404 Type: Problem
    not_found
  • 421 Type: Problem
    wrong_region
  • 429 Type: Problem
    rate_limited or quota_exceeded
  • default Type: Problem
    internal
GET /sig/packages/{package_id}/documents/{document_id}/content · curl
curl "https://api.unforged.sh/sig/packages/{package_id}/documents/{document_id}/content" \
  -H "Authorization: Bearer $UNFORGED_KEY" \
  -H "Unforged-Version: 2026-10-14"
GET /sig/packages/{package_id}/documents/{document_id}/content · Python
import requests

r = requests.get(
    "https://api.unforged.sh/sig/packages/{package_id}/documents/{document_id}/content",
    headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
)
print(r.json())
GET /sig/packages/{package_id}/documents/{document_id}/content · Node.js
const res = await fetch('https://api.unforged.sh/sig/packages/{package_id}/documents/{document_id}/content', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14' },
});
console.log(await res.json());

Download a signed copy

GET /sig/packages/{package_id}/documents/{document_id}/signed

Needs sig:packages:read: See packages, their signers and signed files

The document with everyone's signatures, initials and dates in place. Any later change to the file shows when it's opened. Ready shortly after the last signer signs (the sig.package.completed webhook says so); 404 until then.

Parameters

  • package_id pathrequired Type: string

    The package's id.

  • document_id pathrequired Type: string

    The document's id.

Returns

  • 200
    The signed copy (PDF)
  • 400 Type: Problem
    invalid_request, invalid_version, idempotency_key_required or invalid_signature
  • 401 Type: Problem
    unauthorized
  • 403 Type: Problem
    permission_denied, org_suspended, or address_not_allowed (your organisation only accepts requests from the addresses it has listed)
  • 404 Type: Problem
    not_found
  • 421 Type: Problem
    wrong_region
  • 429 Type: Problem
    rate_limited or quota_exceeded
  • default Type: Problem
    internal
GET /sig/packages/{package_id}/documents/{document_id}/signed · curl
curl "https://api.unforged.sh/sig/packages/{package_id}/documents/{document_id}/signed" \
  -H "Authorization: Bearer $UNFORGED_KEY" \
  -H "Unforged-Version: 2026-10-14"
GET /sig/packages/{package_id}/documents/{document_id}/signed · Python
import requests

r = requests.get(
    "https://api.unforged.sh/sig/packages/{package_id}/documents/{document_id}/signed",
    headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
)
print(r.json())
GET /sig/packages/{package_id}/documents/{document_id}/signed · Node.js
const res = await fetch('https://api.unforged.sh/sig/packages/{package_id}/documents/{document_id}/signed', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14' },
});
console.log(await res.json());

Download the certificate of signing

GET /sig/packages/{package_id}/certificate

Needs sig:packages:read: See packages, their signers and signed files

Who signed, when, where, on what device and how we know, with each document's fingerprint before signing and of its signed copy. The same pages are at the end of every signed copy. Ready with the signed copies; 404 until then.

Parameters

  • package_id pathrequired Type: string

    The package's id.

Returns

  • 200
    The certificate (PDF)
  • 400 Type: Problem
    invalid_request, invalid_version, idempotency_key_required or invalid_signature
  • 401 Type: Problem
    unauthorized
  • 403 Type: Problem
    permission_denied, org_suspended, or address_not_allowed (your organisation only accepts requests from the addresses it has listed)
  • 404 Type: Problem
    not_found
  • 421 Type: Problem
    wrong_region
  • 429 Type: Problem
    rate_limited or quota_exceeded
  • default Type: Problem
    internal
GET /sig/packages/{package_id}/certificate · curl
curl "https://api.unforged.sh/sig/packages/{package_id}/certificate" \
  -H "Authorization: Bearer $UNFORGED_KEY" \
  -H "Unforged-Version: 2026-10-14"
GET /sig/packages/{package_id}/certificate · Python
import requests

r = requests.get(
    "https://api.unforged.sh/sig/packages/{package_id}/certificate",
    headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
)
print(r.json())
GET /sig/packages/{package_id}/certificate · Node.js
const res = await fetch('https://api.unforged.sh/sig/packages/{package_id}/certificate', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14' },
});
console.log(await res.json());

Check a signed copy

POST /sig/check

Needs sig:packages:read: See packages, their signers and signed files

Send a signed copy or certificate as the request body. The answer says whether anything in it has changed since it was signed, when it was time-stamped, and which of your packages it came from. No Idempotency-Key is needed.

Returns

  • 200 Type: SigCopyCheck
    What the check found
  • 400 Type: Problem
    invalid_request, invalid_version, idempotency_key_required or invalid_signature
  • 401 Type: Problem
    unauthorized
  • 403 Type: Problem
    permission_denied, org_suspended, or address_not_allowed (your organisation only accepts requests from the addresses it has listed)
  • 413 Type: Problem
    too_large
  • 421 Type: Problem
    wrong_region
  • 429 Type: Problem
    rate_limited or quota_exceeded
  • default Type: Problem
    internal
POST /sig/check · curl
curl -X POST "https://api.unforged.sh/sig/check" \
  -H "Authorization: Bearer $UNFORGED_KEY" \
  -H "Unforged-Version: 2026-10-14"
POST /sig/check · Python
import requests

r = requests.post(
    "https://api.unforged.sh/sig/check",
    headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
)
print(r.json())
POST /sig/check · Node.js
const res = await fetch('https://api.unforged.sh/sig/check', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14' },
});
console.log(await res.json());