GET /sign-request.ashx?ca Open #
The relying-party CA certificate the wallet pins (PEM).
Responses
200— PEM
Everything behind sign-request.html: upload PDFs, sign them with CodeB Wallet by scanning a QR code, and invite other people by e-mail to sign one after another. The wallet endpoints are capability URLs (128-bit step ids, rate-limited); the requester endpoints need the site’s sign-in.
api=create): 1–10 PDFs, the level (advanced, or qualified = a signature card whose certificate states a qualified signature), optionally “I sign first” and up to 5 invited people (guests: 2) in signing order.eudi-rqes://?client_id=x509_san_dns:<host>&request_uri=<host>/sign-request.ashx?r=<sid>: the requester as a QR code on the page, an invited person by e-mail.?r=), checks it against the pinned CA (?ca), shows who asks and every document (?doc=), signs with the person's signature card (NFC) or the CodeB signing service, and posts the signed PDFs to ?respond= — or declines.?final=).Wallet side designed to follow the OpenID4VP-based signing request of ETSI TS 119 432 and ARF 3.0 topic 16; not certified. “Qualified” is shown only when the signer's certificate states it; there is no trusted-list check. Your own turn stays open 24 hours, an invited person's 72 hours; requests are kept 30 days after they close. Each account sees only its own requests.
/sign-request.ashx?ca Open #The relying-party CA certificate the wallet pins (PEM).
200 — PEM/sign-request.ashx?r={sid} Open #Signed request object of the active step (OpenID4VP, ETSI TS 119 432). Fresh ES256 JWT, typ oauth-authz-req+jwt, exp 5 minutes, x5c chain to the CA from ?ca. Claims: client_id x509_san_dns:<host>, response_mode direct_post, response_uri, state, nonce, signatureQualifier (eu_eidas_qes / eu_eidas_aes), documentDigests (label + SHA-256 per document), documentLocations (?doc URLs). The wallet link is eudi-rqes://?client_id=...&request_uri=<this URL>.
sid (path, required) — string200 — JWT404 — Unknown step409 — not_yet: earlier signers have not signed410 — request_closed429 — Rate limit/sign-request.ashx?doc={sid}.{n}.{token} Open #Input PDF n of the active step (original or the previous signer's PDF).
sid (path, required) — stringn (path, required) — integertoken (path, required) — string200 — PDF404 — Unknown410 — Closed429 — Rate limit/sign-request.ashx?respond={sid} Open #Wallet answer (direct_post): signed PDFs or a decline. Each signed PDF must be an incremental update of the input, byte for byte, with one verifying CMS signature; changes that could hide or replace content are refused; the PAdES level is reported. Idempotent for the same state and body. When an invited signer's answer is accepted, a guest account's signatures for it do not count toward its daily limit.
sid (path, required) — string{
"state": "...",
"documentWithSignature": "...",
"error": "user_cancelled"
}
200 — Accepted400 — invalid_request or invalid_signed_document (with the reason)404 — Unknown410 — request_closed{}
/sign-request.ashx?invite={sid} Open #Invited person's page data (documents, who asks, own turn, wallet link, downloads).
sid (path, required) — string200 — Page data404 — Unknown{}
/sign-request.ashx?final={sid}.{n}.{token} Open #Signed PDF for an invited signer, once everyone has signed.
sid (path, required) — stringn (path, required) — integertoken (path, required) — string200 — PDF404 — Unknown or not yet signed/sign-request.ashx?verify={sid}.{n}.{token} Open #Signature report of the final signed PDF (invited signer). Same token as final=. Every signature in the PDF is checked: integrity of the signed revision, later changes, certificate and timestamp. No check against the EU trusted lists.
sid (path, required) — stringn (path, required) — integertoken (path, required) — string200 — Report404 — Unknown or not yet signed503 — busy (two reports at a time){
"status": "valid",
"summary": "...",
"size": 0,
"trust_note": "...",
"signatures": [
{
"index": 0,
"revision_end": 0,
"covers_whole_file": true,
"subfilter": "...",
"kind": "signature",
"status": "valid",
"integrity": true,
"later_changes": "none",
"later_changes_detail": "...",
"signer": "..."
}
]
}
Bearer access token of this site’s own sign-in (client codeb-admin). Any account, guests included.
/sign-request.ashx?api=create Bearer #Create a signing request. 1-10 PDFs (40 MB each, 50 MB together), signature level qes (signature card whose certificate states a qualified signature) or aes, optional note, self=1 to sign first, invited e-mails in signing order (up to 5; guests 2; 20 invitations a day). Your own turn stays open 24 h, an invited person's 72 h; requests are kept 30 days after they close. The first invited signer is mailed at once when the requester does not sign first.
{
"file": [
"(the file itself)"
],
"label": [
"..."
],
"level": "qes",
"note": "...",
"self": "0",
"invite": [
"person@example.com"
]
}
200 — Created400 — invalid_request (with the reason)401 — Sign-in required409 — limit429 — slow_down{
"id": "...",
"status": "open",
"level": "qes",
"note": "...",
"created": "2026-10-16T10:00:00Z",
"expires": "2026-10-16T10:00:00Z",
"closed_at": "...",
"keep_until": "...",
"current": 0,
"my_turn": true
}
/sign-request.ashx?api=list Bearer #The signed-in user's own signing requests. Each account sees only its own requests.
200 — List401 — Sign-in required{
"requests": [
{
"id": "...",
"status": "open",
"level": "qes",
"note": "...",
"created": "2026-10-16T10:00:00Z",
"expires": "2026-10-16T10:00:00Z",
"closed_at": "...",
"keep_until": "...",
"current": 0,
"my_turn": true
}
]
}
/sign-request.ashx?api=status Bearer #One request (polled by the page).
id (query, required) — string200 — Request401 — Sign-in required404 — Not found or another account's{
"id": "...",
"status": "open",
"level": "qes",
"note": "...",
"created": "2026-10-16T10:00:00Z",
"expires": "2026-10-16T10:00:00Z",
"closed_at": "...",
"keep_until": "...",
"current": 0,
"my_turn": true
}
/sign-request.ashx?api=invite Bearer #Add invited signers at the end of an open request.
{
"id": "...",
"emails": [
"person@example.com"
]
}
200 — Request400 — invalid_request404 — not_found409 — not_open, already_invited or limit429 — slow_down{
"id": "...",
"status": "open",
"level": "qes",
"note": "...",
"created": "2026-10-16T10:00:00Z",
"expires": "2026-10-16T10:00:00Z",
"closed_at": "...",
"keep_until": "...",
"current": 0,
"my_turn": true
}
/sign-request.ashx?api=resend Bearer #Send the invitation e-mail again to the invited person whose turn it is. Owner only, open request; at most 3 times per signer, not twice within a minute; counts as an invitation for the daily limit. The summary's mail field says whether the mail was handed to the mail server.
{
"id": "..."
}
200 — Request404 — not_found409 — not_open, not_waiting, resend_limit or limit429 — slow_down502 — mail_failed: could not be handed to the mail server{
"id": "...",
"status": "open",
"level": "qes",
"note": "...",
"created": "2026-10-16T10:00:00Z",
"expires": "2026-10-16T10:00:00Z",
"closed_at": "...",
"keep_until": "...",
"current": 0,
"my_turn": true
}
/sign-request.ashx?api=withdraw Bearer #Withdraw an open request (the invited person whose turn it was is told).
{
"id": "..."
}
200 — Done404 — not_found409 — not_open{}
/sign-request.ashx?api=delete Bearer #Delete a request and its documents.
{
"id": "..."
}
200 — Done404 — not_found409 — not_open{}
/sign-request.ashx?api=download Bearer #Download an original or the (latest) signed PDF of an own request.
id (query, required) — stringn (query, required) — integerkind (query, required) — string200 — PDF400 — invalid_request404 — Not found or no longer kept/sign-request.ashx?api=verify Bearer #Signature report of an original or signed PDF of an own request. 30 per minute per account.
id (query, required) — stringn (query, required) — integerkind (query, required) — string200 — Report400 — invalid_request401 — Not signed in404 — Not found or no longer kept429 — slow_down503 — busy{
"status": "valid",
"summary": "...",
"size": 0,
"trust_note": "...",
"signatures": [
{
"index": 0,
"revision_end": 0,
"covers_whole_file": true,
"subfilter": "...",
"kind": "signature",
"status": "valid",
"integrity": true,
"later_changes": "none",
"later_changes_detail": "...",
"signer": "..."
}
]
}
/sign-request.ashx?api=verify-upload Bearer #Signature report of any PDF (not stored). The body is the PDF itself (at most 40 MB). Nothing is stored. 10 per minute per account. The page sends a local file only when it contains signatures and the user asks for the check.
"(the file itself)"
200 — Report400 — invalid_request (not a PDF)401 — Not signed in413 — Larger than 40 MB429 — slow_down503 — busy{
"status": "valid",
"summary": "...",
"size": 0,
"trust_note": "...",
"signatures": [
{
"index": 0,
"revision_end": 0,
"covers_whole_file": true,
"subfilter": "...",
"kind": "signature",
"status": "valid",
"integrity": true,
"later_changes": "none",
"later_changes_detail": "...",
"signer": "..."
}
]
}
Open sign-request.html, sign in, upload the PDF, choose whether you sign first and enter the e-mail addresses of the people who should sign, in order. Each person gets an e-mail when it is their turn and signs in CodeB Wallet; at the end everyone gets a link to the signed PDF.
Advanced: any signature source in CodeB Wallet, the person's signature card or the CodeB signing service. Qualified: only a signature card whose certificate states a qualified signature. CodeB shows 'qualified' only as stated in the certificate; it does not check the EU trusted lists.
That it is an incremental update of exactly the PDF the signer received, with one CMS signature that verifies and a certificate valid at the signing time, and that no change could hide or replace content. The PAdES level (B-B, B-T, B-LT, B-LTA) is reported.
The request list shows for the invited person whose turn it is whether the e-mail was handed to the mail server or failed, and a 'Send e-mail again' button (at most 3 times, once a minute).
Yes. The viewer on sign-request.html lists every signature on the right, like a desktop PDF reader: whether the signed part is unchanged, whether anything was changed afterwards, who signed, the certificate and any timestamp. The same report is available from the API (api=verify, api=verify-upload, verify=). Certificates are not checked against the EU trusted lists.
Yes, when a time-stamp server answers: CodeB Wallet asks the CodeB time-stamp service (/rqes/csc/v2/signatures/timestamp, then /rqes/csc/v2/signatures/tsa as fallback) and embeds the token, so the signature is PAdES-B-T. If neither answers, the PDF is signed without a time stamp (PAdES-B-B). The signature report shows which one a signature has.
No. A guest account can sign 5 documents per UTC day with the CodeB signing service; signatures given as an invited signer in someone else's request are given back once the request accepts the signed PDF.
Machine-readable: /openapi.json (OpenAPI 3.1, also at /.well-known/openapi.json) · All public APIs · Questions