Skip to main content

Partner Endpoints

Partner endpoints live under /api/v2/partner/* and are authenticated with X-API-Key. They mirror the internal endpoints but are scoped to your organization.

Endpoints

E-sign + envelope lifecycle

MethodPathScopeDescription
GET/partner/envelopesenvelopes:readList envelopes
GET/partner/envelopes/:idenvelopes:readGet envelope
GET/partner/envelopes/:id/statusenvelopes:readGet status only (lightweight polling)
POST/partner/envelopesenvelopes:writeCreate envelope (e-sign or paper)
POST/partner/envelopes/:id/uploadenvelopes:writeUpload pre-signed PDF (paper flow)
POST/partner/envelopes/:id/voidenvelopes:writeVoid / cancel envelope
POST/partner/envelopes/:id/remindenvelopes:writeSend signing reminder(s)
GET/partner/envelopes/:id/signing-linksenvelopes:readGet per-signer signing URLs

E-vault — vault-in, retrieval, vault-out

MethodPathScopeDescription
POST/partner/envelopes/:id/vault-in-signedvault:writeVault a completed e-sign envelope (manual / recovery)
POST/partner/envelopes/:id/vault-in-uploadvault:writeVault a paper / uploaded PDF
GET/partner/envelopes/:id/vault/signed-urlvault:readDownload URL (authoritative)
GET/partner/envelopes/:id/vault/copy/signed-urlvault:readDownload URL (non-authoritative copy)
GET/partner/envelopes/:id/vault/certificatecompliance:readUCC §9-105 compliance certificate JSON
GET/partner/envelopes/:id/compliancecompliance:readRun compliance check synchronously
POST/partner/envelopes/:id/vault-outvault:releaseRelease authoritative copy out of the live vault

Configuration

MethodPathScopeDescription
PATCH/partner/webhookenvelopes:writeUpdate webhook URL / secret
POST/embed/tokenesign:write / vault:readMint embed token

How partner endpoints work

  1. Auth: All partner endpoints use X-API-Key: lk_...
  2. Scoping: Every response is automatically scoped to the organization tied to the key
  3. No org header required: The organization is derived from the API key
  4. Scoped by permission: Each endpoint requires an explicit scope on your key — see Scopes

Creating an envelope

POST /partner/envelopes supports two flows:

  • envelope_kind: "esign" (default) — DocuSeal-driven signing. Pass template_id and an optional signers[] array for multi-signer deals. Returns a sign_url.
  • envelope_kind: "paper" — Partner-uploaded pre-signed PDF. Skips DocuSeal. Next step is POST /partner/envelopes/:id/upload.

E-sign flow

{
"customer_email": "[email protected]",
"customer_name": "Jane Buyer",
"template_id": "tmpl_abc123",
"signers": [
{ "email": "[email protected]", "name": "Jane Buyer", "role": "Buyer" },
{ "email": "[email protected]", "name": "John Cosigner", "role": "Co-Signer" }
]
}

customer_email and customer_name are always required (used for customer record lookup/upsert). The signers array, when provided, determines the DocuSeal submitter list — each entry maps to one signing URL returned by GET .../signing-links.

tip

When using signers[], the role values must match the submitter role names defined in your DocuSeal template. If omitted, roles default to Signer 1, Signer 2, etc.

Paper / pre-signed PDF flow

{
"customer_email": "[email protected]",
"customer_name": "Jane Buyer",
"envelope_kind": "paper"
}

Returns an envelope with status: "uploaded" and envelope_kind: "paper". Then upload the PDF (see below).

Uploading a paper PDF

POST /partner/envelopes/:id/upload accepts multipart/form-data with field file. Allowed types: application/pdf, image/png, image/jpeg. Max 50 MB.

curl -X POST "https://api.stg.loyva.net/api/v2/partner/envelopes/env_abc/upload" \
-H "X-API-Key: lk_..." \
-F "file=@./signed-contract.pdf"

Response (201 Created):

{
"data": {
"path": "org_abc/env_abc/upload_20260427120000.pdf",
"hash": "<sha256>",
"size": 184320,
"content_type": "application/pdf"
}
}

The PDF lives in ucc-uploads until you trigger vault-in (next section).

Vault-in — moving a document into the UCC vault

There are two vault-in endpoints, picked based on how the document was acquired.

POST /partner/envelopes/:id/vault-in-signed — for completed e-sign envelopes

Use when the envelope was signed via DocuSeal. The queue worker normally vaults automatically once the submission.completed webhook fires; this endpoint is a manual trigger / recovery path if the queue missed the message. Idempotent — returns 200 with the existing envelope row if vault_file_path is already set.

The pipeline runs synchronously: download signed PDF → SHA-256 → upload authoritative + non-authoritative copies → generate UCC §9-105 compliance certificate → generate vault custody record PDF → assign custodian → set status to vaulted. The vault.stored webhook fires.

POST /partner/envelopes/:id/vault-in-upload — for paper / uploaded PDFs

Use after POST /envelopes/:id/upload. Same pipeline, no DocuSeal step. Requires is_upload: true and a non-null upload_file_path on the envelope.

Both endpoints return the updated envelope row:

{
"data": {
"envelope_id": "env_abc",
"status": "vaulted",
"...": "..."
}
}

Vault-out — releasing the authoritative copy

POST /partner/envelopes/:id/vault-out is the end-of-lifecycle action: it releases the authoritative package out of the live vault to a designated recipient (typically a secured party at loan funding).

Irreversible

Vault-out copies the live vault package into an immutable archive prefix (vault-out-archive/{stamp}/) and deletes the live authoritative path as part of UCC single-locus enforcement. Status becomes vaulted_out and live vault pointers are cleared. The archive is preserved for audit but cannot be re-vaulted.

Request body — all fields required, two acknowledgments must be the literal true:

{
"recipient_name": "First National Bank",
"recipient_organization": "First National Bank, N.A.",
"recipient_email": "[email protected]",
"purpose_of_release": "Loan funded — release to secured party",
"acknowledge_authoritative_copy": true,
"acknowledge_chain_of_custody": true,
"authorized_signature": "Jane Doe, Operations Manager"
}

Response — four short-lived (1 hr) signed URLs into the archive:

{
"data": {
"authoritative_signed_url": "https://...",
"authoritative_filename": "authoritative.pdf",
"certified_vaulted_copy_signed_url": "https://...",
"certified_vaulted_copy_filename": "certified-vaulted-copy.pdf",
"compliance_certificate_signed_url": "https://...",
"compliance_certificate_filename": "ucc-compliance-certificate.json",
"vault_custody_record_signed_url": "https://...",
"vault_custody_record_filename": "vault-custody-record.pdf"
}
}

The four artifacts:

  • authoritative_signed_url — the signed PDF that was vaulted (now released).
  • certified_vaulted_copy_signed_url — human-readable release certificate (PDF) capturing recipient, purpose, chain of custody, and authorized signature.
  • compliance_certificate_signed_url — UCC §9-105 compliance certificate JSON, captured at vault-in time.
  • vault_custody_record_signed_url — vault custody record PDF (historical record from vault-in).

URLs expire after 1 hour. Re-call the endpoint to mint fresh URLs.

Voiding an envelope

POST /partner/envelopes/:id/void cancels the envelope. Terminal envelopes (status completed, declined, or already voided) return a 409.

{ "reason": "Customer withdrew before signing" }

The reason field is optional. An envelope.voided webhook event is dispatched to your configured endpoint immediately after the void.

Sending signing reminders

POST /partner/envelopes/:id/remind re-sends the DocuSeal invitation email to pending signers. Only works for envelopes with status sent or viewed.

{ "signer_email": "[email protected]" }

Omit signer_email to remind all pending signers at once. Returns the list of reminded addresses and an envelope.reminder_sent webhook event.

{
"data": {
"reminded": ["[email protected]"],
"count": 1
}
}

Managing your webhook

PATCH /partner/webhook lets you update your delivery URL and HMAC signing secret without contacting Loyva. Changes take effect on the next delivery.

{
"webhook_url": "https://your-app.com/webhooks/loyva",
"webhook_secret": "a-random-string-at-least-16-chars"
}

Pass null for either field to clear it. The response confirms what changed but never echoes the secret value. See Webhooks for signature verification details.

End-to-end flows

E-sign + auto-vault (typical)

  1. POST /partner/envelopes with template_id → returns sign_url
  2. Customer signs via DocuSeal
  3. vault.stored webhook fires automatically
  4. GET /partner/envelopes/:id/vault/signed-url to download the authoritative PDF
  5. (Optional) POST /partner/envelopes/:id/vault-out at end of lifecycle

E-sign with manual vault recovery

If the queue worker missed the submission.completed event:

  1. ... envelope reaches status: "completed" but vaulted: false
  2. POST /partner/envelopes/:id/vault-in-signed → re-runs the pipeline

Paper / pre-signed PDF

  1. POST /partner/envelopes with envelope_kind: "paper" → envelope created with status: "uploaded"
  2. POST /partner/envelopes/:id/upload (multipart) → PDF stored in ucc-uploads
  3. POST /partner/envelopes/:id/vault-in-upload → vaulted, certificate generated
  4. (Optional) POST /partner/envelopes/:id/vault-out at end of lifecycle