Signing Worker Protocol
POST /v1/credential
Return the certificate chain the signer will sign with, and the signature format your provider returns
Private beta. Qualified signatures are available on request. Request access and we enable them for your account. SWP/1 is in beta and may change.
The first call of a signing session. Find, or issue, the signer’s certificate at your provider and return its chain. The response also sets the session’s signature format: raw or cms.
For raw, SignatureAPI needs the certificate before it can compute the digest. For cms, your provider builds the signature, so the certificate can wait until sign.
Answer completed right away whenever your provider doesn’t need the signer yet. An interaction that identifies the signer and takes their approval at once belongs in authorize. See Choose your provider’s model.
Request
The common request fields, nothing else. When the request resumes after a redirect, it also carries "callback": { "code": "..." }.
Response
{
"status": "completed",
"credential": {
"id": "cred_7Qk...",
"certificates": [
"-----BEGIN CERTIFICATE-----\n...signer...\n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----\n...intermediate...\n-----END CERTIFICATE-----"
],
"key_algo_oids": ["1.2.840.10045.4.3.2"],
"expires_at": "2026-08-24T17:10:00Z"
}
}
| Field | raw | cms | Description |
|---|---|---|---|
credential.id | Required | Required | Your handle on the credential. SignatureAPI sends it back as credential_id to authorize and sign. |
credential.signature_format | Optional | Required | raw or cms. Leave it out for raw. Any other value fails the session with worker response invalid: credential.signature_format. |
credential.certificates | Required | Optional | The chain in PEM, signer certificate first. The signature must verify against the first certificate. For cms, a signer certificate given here must match the one in the sign response. |
credential.key_algo_oids | Required | Optional | The signature algorithms the key supports, as dotted OIDs. SignatureAPI picks one and sends it as sign_algo_oid. For cms, it’s used only together with certificates. See Supported algorithms. |
credential.max_signature_size | Not allowed | Optional | The largest CMS your provider returns, in bytes: 1 to 53,248. Defaults to 24,576. See Signature size. |
credential.expires_at | Optional | Optional | Set it for a certificate issued on the spot. SignatureAPI checks it before authorize and again before sign. If it has passed, the session fails with credential_expired, and the signer retries in a new session. |
List only algorithms the key really supports.
A max_signature_size on a raw credential fails the session with worker response invalid: credential.max_signature_size. A value outside 1 to 53,248 fails it with max-signature-size-unsupported.
A cms credential without a certificate
When your provider issues the signer’s certificate during signing, return only the ID and the format:
{
"status": "completed",
"credential": {
"id": "cred_7Qk...",
"signature_format": "cms",
"expires_at": "2026-08-24T17:10:00Z"
}
}
The certificate then arrives in the sign response.
A separate identification step
Some providers must identify the signer in a separate step before they can return a certificate, for example to issue a one-shot certificate for a raw signature. Then answer pending with an action_url, or with poll_after when the signer identifies in an app. The ceremony shows Confirm your identity to continue while it waits on a redirect. On a redirect, send the signer’s browser to callback_url with a single-use code when they are done. SignatureAPI then calls credential again with that code, and you return the certificate.
A request that carries callback.code must get a decision: completed or failed, never pending. See Pending steps.
Static certificate
A static certificate is raw only. If every signer uses the same certificate and your worker can’t return it, the account can give a static certificate when it connects the worker. Signing sessions then never call credential, and authorize and sign carry "credential_id": "static".
The request authentication check still sends two POST /v1/credential requests, so serve the endpoint and authenticate it either way.