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 original signing email (with a fresh copy of each signer's link) to signers who have not yet signed. Only works for envelopes with status sent or viewed.

Signing order is preserved: on an envelope sent with signing_order: "preserved", only the signer whose turn it is receives the reminder. Signers further down the order are emailed automatically when the signer before them completes, and asking to remind one of them directly returns 422.

{ "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