Sign Recipient via API (Interface Signing)
POST/openapi/v1/envelopes/{envelopeId}/recipients/{recipientId}/sign
The customer server completes signing on behalf of a signer using their Signing PIN (the signer does not enter the signing page).
- The signer must have a Signing PIN configured and must have accepted the ERSD disclosure toward the sender (first-time consent happens on the signing page / frontend); an error is returned if either is missing
- Idempotency: the
Idempotency-Keyheader takes precedence over the bodyIdempotencyKey; sending neither is an error. Replaying the same key returns the previous successful result (IdempotentReplay=true) - Asset resolution: signing controls not explicitly bound in
TabsuseSignatureId/SealIdas the default asset; at least one must be available. The signature/seal must belong to the signer envelopeIdandrecipientIdare path parameters, not part of the body
Applicable controls & default assets
- This endpoint signs / seals on behalf of the signer and only covers signing-type controls (e.g.
signHere,initialHere,stamp). It does not fill other data-entry controls (text/date/email/number, etc.); envelopes with such unfilled fields must first be completed on the signing page by the signer, otherwise a "field not filled" error is returned Tabsis optional — usually no per-control binding is needed: signing controls not listed inTabsfall back toSignatureId(signature) orSealId(seal) as the default asset
Credential (JWE)
Encrypt the signing PIN with JWE (RFC7516): alg=RSA-OAEP-256, enc=A256GCM.
- Public key:
GET {baseUrl}/.well-known/jwks.json, take theuse=enckey (keep itskid). - Plaintext payload:
{"typ":"sign_pin","secret":"<PIN>","context":{"userId":"<recipient UserId>","envelopeId":"<envelopeId in URL>","recipientId":"<recipientId in URL>"},"iat":<sec>,"exp":<iat+60>,"jti":"<uuid>"}- Encrypt to a 5-segment Compact string (
protected.encryptedKey.iv.ciphertext.tag) and put it inCredential.
Notes: must be 5 segments (WebCrypto: split the trailing 16-byte tag into its own segment); header is the AAD; exp<=60s, jti single-use (re-sign on retry); context must match the recipient and URL.
Plaintext PIN: not accepted by default — contact us to enable it.
Request Parameters
Header Parameters
AuthorizationRequiredstring
Bearer <access_token>
X-Operator-User-IdOptionalstring
Operator user ID. Omit under authorization-code mode (the authorized user is used); optional under client-credentials mode, defaulting to the system user ID.
Idempotency-KeyOptionalstring
Idempotency key (either this header or body IdempotencyKey; header takes precedence)
Request Body
application/jsonSignatureIdOptionalstring
Signature asset (the default when a control is not explicitly bound, along with SealId; one of the two must be usable)
SealIdOptionalstring
Seal asset (the default when a control is not explicitly bound, along with SignatureId)
TabsOptionalarray<object>
Tab-level asset bindings (optional). Signing controls absent from Tabs fall back to the SignatureId / SealId default asset.
Sub-properties
TabIdRequiredstring
Tab ID (required)
SignatureIdOptionalstring
Signature asset ID for this tab (optional)
SealIdOptionalstring
Seal ID for this tab (optional)
IdempotencyKeyOptionalstring
Idempotency key (optional). Either this or the Idempotency-Key header is required; the header takes precedence. The idempotency key may be reused, but each retry must carry a newly issued Credential (credentials are one-time tickets and are not replayed with the idempotency key).
CredentialOptionalstring
JWE-encrypted credential (RSA-OAEP-256 + A256GCM, typ=sign_pin; context carries userId/envelopeId/recipientId). Valid for 60 seconds and single-use. Either Credential or SigningPin must be provided.
SigningPinOptionalstring
Signing PIN (plaintext not accepted by default; contact us to enable)
Response Parameters
Response.Data
EnvelopeStatusOptionalstring
Current envelope status
RecipientStatusOptionalstring
Recipient status after this signing
SignedAtOptionalstring
Signing completion time (RFC3339)
EnvelopeCompletedOptionalboolean
Whether the envelope is completed (all signers signed)
IdempotentReplayOptionalboolean
Whether this is an idempotent replay (returns the previous successful result verbatim)
Error Codes
| Error Code | Description |
|---|---|
INVALID_REQUEST | Invalid request (missing idempotency key / empty path parameter etc.) |
NOT_FOUND | Envelope not found |
RECIPIENT.NOT_RECIPIENT | The recipientId is not a signer of this envelope (or is a carbon copy) |
ENVELOPE.INVALID_STATUS | Envelope status does not allow signing (completed / voided / draft etc.) |
SIGNING.RECIPIENT_ALREADY_SIGNED | The signer has already signed |
SIGNING.RECIPIENT_DECLINED | The signer has declined |
SIGNING.CONSENT_REQUIRED | The signer has not accepted the ERSD disclosure yet |
AUTH.PIN_NOT_CONFIGURED | The signer has no Signing PIN configured |
AUTH.PIN_INVALID | Signing PIN is incorrect |
AUTH.PIN_LOCKED | Too many incorrect PIN attempts; temporarily locked |
AUTH.CREDENTIAL_REQUIRED | Plaintext is not allowed for this app; use a JWE Credential |
AUTH.CREDENTIAL_INVALID | Credential is invalid (decryption/binding failed or replayed) |
AUTH.CREDENTIAL_EXPIRED | Credential expired (check client clock and retry) |
SIGNING.ENVELOPE_NOT_SIGNABLE | The envelope is not signable now |
SIGNING.RECIPIENT_NOT_SIGNABLE | The recipient is not signable now |
INTERNAL_ERROR | 服务内部错误 |