Hosted and external signing session orchestration.
GET/signing/client-sessionsيتطلب مصادقة
Find a participant's client signing session by contract
For hosts that know the contract (and maybe the participant) but not the
session id. Returns the participant's newest open session, else its
newest session of any status.
- **Signer token**: pinned to its own contract and participant;
`participantId` may be omitted. Any other contract or participant returns `403`.
- **Machine key** (`contracts:read`): when `participantId` is omitted and
the contract has exactly one pending `integrator_managed` signer, that
signer is used; otherwise `409 PARTICIPANT_REQUIRED`.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| contractId | query | string | نعم |
|---|
| participantId | query | string | لا |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
الاستجابات
200Session detailsdefaultStandardized API error
POST/signing/client-sessionsيتطلب مصادقة
Create client-side signing session (advanced/enterprise)
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
contractIdstringمطلوبparticipantIdstringمطلوبproviderKeystringمطلوبproviderTypestringchannelstringsessionTtlMinutesinteger
الاستجابات
201Session createddefaultStandardized API error
GET/signing/client-sessions/{sessionId}يتطلب مصادقة
Get client signing session (advanced/enterprise)
Callable with a machine key or with the signer token that the access
route issued for **this** session (SigningKit). A signer token for any
other session gets `403 AUTH_SIGNER_TOKEN_SESSION_MISMATCH`; once the
session has ended, or its contract or participant can no longer sign,
the token gets `410 SESSION_EXPIRED`. Signer tokens are
limited to 60 requests/min each. SDK callers send `X-SDK-Platform` and
`X-SDK-Version`; an SDK older than the organization minimum gets
`426 SDK_OUTDATED`. Every response carries `X-Request-Id`.
**Encrypted channel (SigningKit v2).** For signer tokens this route, `package`,
`identity-session[/complete]`, `identity-checks`, `media`, `registration-request`,
`complete`, `cancel` and `provider-submission` are sealed routes: after
`POST .../handshake` they take and return sealed envelopes. Under the
organization policy `required`, this route answers metadata only
(`id`, `status`, `contractId`, `participantId`, `expiresAt`, `secureChannel`,
`sdk.channelKeys`) before a handshake, and plain requests on the other sealed
routes get `426 CHANNEL_REQUIRED`. Machine keys are never sealed.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
الاستجابات
200Session detailsdefaultStandardized API error
POST/signing/client-sessions/{sessionId}/cancelيتطلب مصادقة
Cancel client signing session (advanced/enterprise)
Callable with a machine key or with the signer token that the access
route issued for **this** session (SigningKit). A signer token for any
other session gets `403 AUTH_SIGNER_TOKEN_SESSION_MISMATCH`; once the
session has ended, or its contract or participant can no longer sign,
the token gets `410 SESSION_EXPIRED`. Signer tokens are
limited to 60 requests/min each. SDK callers send `X-SDK-Platform` and
`X-SDK-Version`; an SDK older than the organization minimum gets
`426 SDK_OUTDATED`. Every response carries `X-Request-Id`.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
reasonstringstagestringJourney step the signer cancelled at (SigningKit); stored as `cancelStage` and published in the webhook.
الاستجابات
200Session cancelleddefaultStandardized API error
POST/signing/client-sessions/{sessionId}/completeيتطلب مصادقة
Submit signed artifact to complete client signing (advanced/enterprise)
Callable with a machine key or with the signer token that the access
route issued for **this** session (SigningKit). A signer token for any
other session gets `403 AUTH_SIGNER_TOKEN_SESSION_MISMATCH`; once the
session has ended, or its contract or participant can no longer sign,
the token gets `410 SESSION_EXPIRED`. Signer tokens are
limited to 60 requests/min each. SDK callers send `X-SDK-Platform` and
`X-SDK-Version`; an SDK older than the organization minimum gets
`426 SDK_OUTDATED`. Every response carries `X-Request-Id`.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
sessionNoncestringمطلوبinputHashEchostringمطلوبidentityCheckIdsarrayIdentity checks the device considers part of this completion (SigningKit). The server gates on its own records; while a required kind has no passed record the call answers `409 IDENTITY_REQUIRED`.journeyIdstringSDK journey id, stored on the session for the debugger (SigningKit).artifactobjectمطلوبproviderReceiptobjectWhen the session has a signing-provider registration (SigningKit v2), must carry `transactionId` and `tcspTransactionId` from the provider; the signed PDF's PAdES signature is then verified (against the configured certification-provider trust anchors when present).registrationRefstringRequired when the session has a signing-provider registration (SigningKit v2); the `registrationRef` of the registration request the device used.
الاستجابات
200Completion accepted400`REQUEST_BODY_INVALID` — the body is not parseable JSON or multipart413`PAYLOAD_TOO_LARGE` — the request body exceeds the route limitdefaultStandardized API error
POST/signing/client-sessions/{sessionId}/eventsيتطلب مصادقة
Ship SDK telemetry events for the session (SigningKit)
Batch of up to 100 events / 512 KB validated against the SDK's
`events.schema.json`. A batch is never refused for one bad event: the
`202` response reports `accepted` and `dropped[]` (reasons `invalid`,
`context_mismatch`, `budget_exceeded`, `write_failed`). `eventId` is
idempotent. Signer tokens get 600 events per minute and every
organization has a daily budget; both limits answer `429` with
`Retry-After`. Events are redacted server-side (allow-listed attributes,
200-char strings, no base64, no tokens) and expire after the
organization's telemetry retention.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
الاستجابات
202Batch accepted (`data.accepted`, `data.dropped[]`)400`REQUEST_BODY_INVALID` — the body is not parseable JSON or multipart413`PAYLOAD_TOO_LARGE` — the request body exceeds the route limitdefaultStandardized API error
POST/signing/client-sessions/{sessionId}/handshakeيتطلب مصادقة
Encrypted channel key agreement (SigningKit v2)
Signer token only (machine keys never use the channel). The SDK sends an
ephemeral P-256 public key and a 32-byte nonce; the server answers its own
ephemeral key, nonce and an Ed25519 signature over the transcript with the
key published at `GET /api/public/sdk/keys`. Both sides derive per-direction
AES-256-GCM keys with HKDF-SHA256. Afterwards the sealed routes take and
return `application/vnd.platform.sealed+json` envelopes
(`{ v, kid, seq, nonce, ct }`; bodyless and multipart requests carry the
envelope in `X-Channel-Envelope`). Byte-level rules and known-answer
vectors: the SigningKit API contract §14 and `test-vectors/channel-v1.json`.
The organization's `sealedChannel` policy decides whether plain requests are
still accepted (`required` gives `426 CHANNEL_REQUIRED`). 10 handshakes per token
per minute. A new handshake replaces the keys.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
clientPubstringمطلوبBase64 of the 65-byte uncompressed P-256 ephemeral public key.clientNoncestringمطلوبBase64 of 32 random bytes.sdkobject
الاستجابات
201Handshake accepted (`data.handshake = { kid, serverPub, serverNonce, sig, expiresAt }`)defaultStandardized API error
POST/signing/client-sessions/{sessionId}/identity-checksيتطلب مصادقة
Record an identity check for the session's signer (SigningKit)
Posted by the mobile SDK after each identity step (`otp`, `document`,
`biometrics`), or by a machine key on the signer's behalf. The server
assigns `attempt`, `receivedAt`, `integrity` and `ipAddress`, re-runs the
document field rules (it may force `outcome: failed` with
`serverDecision.code` `DOCUMENT_REJECTED` or `IDENTITY_MISMATCH`), encrypts
the payload at rest and returns the participant's updated `identity`
block. Records are append-only. Send `Idempotency-Key`
(`<journeyId>:<step>:<attempt>`) so a retried post replays the first record.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
kindstringمطلوبproviderobjectمطلوبreferenceIdstringمطلوبoutcomestringمطلوبsourcestringrecordedAtstringمطلوبtimezonestringjourneyIdstringdeviceobjectDevice snapshot (platform, osVersion, model, deviceId, appId, appVersion, sdkVersion, providerSdkVersions, locale, networkType, rooted, emulator).locationobjectmediaarrayruleResultsarrayerrorobjectpayloadobjectمطلوبProvider result (≤ 256 KB). Encrypted at rest; only its SHA-256 (`integrity`) is stored in clear.
الاستجابات
201Identity check recorded (`data.identityCheck`)400`REQUEST_BODY_INVALID` — the body is not parseable JSON or multipart413`PAYLOAD_TOO_LARGE` — the request body exceeds the route limitdefaultStandardized API error
POST/signing/client-sessions/{sessionId}/identity-sessionيتطلب مصادقة
Start (or resume) the provider-run identity session (SigningKit v2)
Signer token only; a sealed route. The server creates the eKYC provider
session server-to-server for the participant's person record and returns
only what the provider's mobile SDK needs for this journey
(`baseUrl`, `bundleKey`, `sessionToken`, `language`, `documentType`,
`userReferenceId`) as `data.identitySession`. Idempotent per signing
session: an open identity session is returned again (200); once the
participant is verified the answer is 200 with `status: completed` and no
hand-off, so the SDK skips the step. The device never receives the
provider's server credentials and never sends identity data back.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
الاستجابات
200Existing identity session (or already verified)201Identity session created (`data.identitySession`)defaultStandardized API error
POST/signing/client-sessions/{sessionId}/identity-session/completeيتطلب مصادقة
Report that the device finished the provider flow (SigningKit v2)
Signer token only; a sealed route. `outcome` is what the provider's SDK
reported (`approved`, `rejected`, `exited`, `error`) and decides nothing:
the server fetches the result and the images from the provider,
evaluates its rules (a document number different from the participant's
registered one is a hard block) and records the identity checks. `exited`
cancels the identity session. Answers `202` with
`data.identitySession = { id, status, decision, rejection }`; the SDK then
polls the session until `identity.status` is `completed` or `failed`.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
identitySessionIdstringoutcomestringمطلوبdeviceIDstringproviderCodestringflowLogarray
الاستجابات
202Report accepted (`data.identitySession`)defaultStandardized API error
POST/signing/client-sessions/{sessionId}/mediaيتطلب مصادقة
Upload identity media for the next identity check (SigningKit)
Multipart upload. Field names are the media kinds: `id_front`, `id_back`,
`selfie` (JPEG/PNG/WebP, 2 MB each) and `liveness_frames` (repeated; up
to 60 files, 100 KB each, 6 MB in total). Frames are rendered server-side
into one animated WebP returned as `liveness_animation`. The response
lists opaque `storageRef`s to reference from the identity check; media is
stored encrypted and is never returned to the device. Signer tokens are
limited to 20 uploads per minute (`429` with `Retry-After`).
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
الاستجابات
201Stored media (`data.media[]`)400`REQUEST_BODY_INVALID` — the body is not parseable JSON or multipart413`PAYLOAD_TOO_LARGE` — the request body exceeds the route limitdefaultStandardized API error
GET/signing/client-sessions/{sessionId}/packageيتطلب مصادقة
Retrieve source signing package (advanced/enterprise)
Callable with a machine key or with the signer token that the access
route issued for **this** session (SigningKit). A signer token for any
other session gets `403 AUTH_SIGNER_TOKEN_SESSION_MISMATCH`; once the
session has ended, or its contract or participant can no longer sign,
the token gets `410 SESSION_EXPIRED`. Signer tokens are
limited to 60 requests/min each. SDK callers send `X-SDK-Platform` and
`X-SDK-Version`; an SDK older than the organization minimum gets
`426 SDK_OUTDATED`. Every response carries `X-Request-Id`.
When the participant has identity fields (SigningKit v2), the package
waits for identity verification (`409 IDENTITY_SESSION_NOT_COMPLETED`)
and then carries the document re-rendered with the verified values;
`inputHash` is that render's hash.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| mode | query | string | لا |
|---|
الاستجابات
200Signing source packagedefaultStandardized API error
POST/signing/client-sessions/{sessionId}/provider-submissionيتطلب مصادقة
Report the signed contract's filing with the certification provider (SigningKit v2)
Signer token only; a sealed route; the one write a completed session
accepts. After `/complete` the session's `providerSubmission.status` is
`pending`; the device reports `submitted` or `failed` (with the
provider's code) after the registration SDK's contract submission.
`submitted` is terminal and idempotent; a receipt that differs from the
one accepted at completion is refused. Webhooks
`contract.provider_submission.pending|completed|failed`.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
registrationRefstringمطلوبtransactionIdstringمطلوبtcspTransactionIdstringمطلوبsubmittedAtstringمطلوبstatusstringمطلوبerrorobject
الاستجابات
200Recorded (`data.providerSubmission = { status, attempts, submittedAt }`)defaultStandardized API error
POST/signing/client-sessions/{sessionId}/registration-requestيتطلب مصادقة
Signing-provider registration request (SigningKit v2)
Signer token only; a sealed route; 5 per minute per token. Requires the
organization's external signing provider to be enabled, the journey's app
registered and active (`X-SDK-App-Id`, `X-SDK-App-Name`, read by the SDK
from its host package), an approved identity session, an allowed ID type
and the signer's mobile number. The server mints the `TransactionID`
per attempt, builds the provider payload from the server-held identity
profile and images, e-seals it (`signedRequestData`, CAdES-B-B over the
canonical JSON) and returns `data.registrationRequest` with the
registration SDK's 20 parameters (`registration`), the certification
provider block (`tcsp`), the signing service block (`signing`, including
the OTP `channelId`) and `signer.nationalId`. Credentials are for one
journey, in memory only. `?purpose=submission` (completed session with an
open provider submission) returns only `registrationRef`, `tcsp` and
`expiresAt`. `501 SIGNING_PROVIDER_REGISTRATION_NOT_CONFIGURED` only when
no e-seal certificate is active; `503 SIGNING_PROVIDER_CERT_EXPIRED`
(with `Retry-After`) when it expired.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| sessionId | path | string | نعم |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| X-SDK-App-Id | header | string | لا |
|---|
| X-SDK-App-Name | header | string | لا |
|---|
| purpose | query | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
الاستجابات
201Registration request built (`data.registrationRequest`)defaultStandardized API error
POST/signing/contracts/{contractId}/external/dispatchيتطلب مصادقة
Trigger external organization signing dispatch (advanced)
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| contractId | path | string | نعم |
|---|
| Idempotency-Key | header | string | لا |
|---|
الاستجابات
200Dispatch resultdefaultStandardized API error
GET/signing/contracts/{contractId}/external/requestsيتطلب مصادقة
List external signing requests for contract (advanced)
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| contractId | path | string | نعم |
|---|
الاستجابات
200Request listdefaultStandardized API error
POST/signing/contracts/{contractId}/participants/{participantId}/accessيتطلب مصادقة
Create signer access (hosted link, or client session + signer token)
Mints access for one signer participant (`action="sign"`). What you get
depends on the participant's `executionChannel`:
- **`platform_hosted`** — the hosted signing URL and link token
(`signingUrl`, `token`). Unchanged; the request body is ignored.
- **`integrator_managed`** (SigningKit / mobile SDK) — opens, or reuses
the open, client signing session for the participant and returns
`sessionId` + `signerToken`. Hand both to your app: the signer token
authenticates the device on
`/signing/client-sessions/{sessionId}`, `/package`, `/complete` and
`/cancel` for **that session only** (`signerBearer`). It expires at
`expiresAt` (default 120 min, max 24 h, never after the session). Once
the session completes, is cancelled or fails the token stays valid for
reads and telemetry only (the SDK replays `complete` and ships its final
events after the fact); expiry revokes it. Calling again returns the same
session with a fresh token.
- any other channel returns `409 SIGNING_EXECUTION_CHANNEL_MISMATCH`.
**Requires the `contracts:send` scope.** It previously accepted
`contracts:read` OR `contracts:send`, so a read-only key could mint a
signing link. The token this returns authenticates the participant and
produces a binding signature — issuing it is not a read. A key without
`contracts:send` receives `403 PERMISSION_DENIED`. A signer token cannot
call this route.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| contractId | path | string | نعم |
|---|
| participantId | path | string | نعم |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
providerKeystringClient signing provider for the session. Defaults to `generic_pdf_signer`.sessionTtlMinutesintegertokenTtlMinutesintegerSigner token lifetime. Defaults to 120; never extends past the session's expiry.
الاستجابات
200Signer access. `data.access` is `HostedSignerAccess` for a
`platform_hosted` participant, `ClientSignerAccess` for an
`integrator_managed` one.defaultStandardized API error
GET/signing/external/providersيتطلب مصادقة
List external signing providers
الاستجابات
200External provider listdefaultStandardized API error
GET/signing/external/requests/{requestId}يتطلب مصادقة
Get external signing request details (advanced)
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| requestId | path | string | نعم |
|---|
الاستجابات
200Request detailsdefaultStandardized API error
POST/signing/external/requests/{requestId}/retryيتطلب مصادقة
Retry external signing request dispatch (advanced)
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| requestId | path | string | نعم |
|---|
| Idempotency-Key | header | string | لا |
|---|
الاستجابات
200Retry resultdefaultStandardized API error
GET/signing/providersيتطلب مصادقة
List client signing providers from registry
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| providerType | query | string | لا |
|---|
الاستجابات
200Provider listdefaultStandardized API error
POST/signing/sdk-eventsيتطلب مصادقة
Ship pre-session SDK telemetry events (SigningKit)
Events emitted before the SDK has resolved its session (security gate,
journey start) carry `sessionId: null` and are posted here with the
contract and participant. They are attached to the participant's session
once it exists (24 hour window). A signer token may only post about its
own contract and participant; a machine key about its own contracts.
Same limits and response shape as the session route.
المعاملات
| الاسم | الموضع | النوع | مطلوب |
|---|
| X-SDK-Platform | header | string | لا |
|---|
| X-SDK-Version | header | string | لا |
|---|
| Idempotency-Key | header | string | لا |
|---|
جسم الطلب
contractIdstringمطلوبparticipantIdstringeventsarrayمطلوب
الاستجابات
202Batch accepted (`data.accepted`, `data.dropped[]`)defaultStandardized API error