API Documentation
All endpoints live under https://signproxy.cfy.performance4.cz/api and expect JSON. PDFs, certificates, and attachments are base64
strings.
Add Authorization: Bearer <token> (create tokens in API Tokens).
In the table below, you can find information on the credit costs for each API call.
PDFs & templates: 20MB. Images: 1MB. Attachments: 10MB. Request body limit: 40MB. Too-large requests return “Request exceeded limit”.
Concurrent API calls per user/IP are throttled; bursts return HTTP 429.
Endpoint overview
| Method | Path | Purpose | Credits |
|---|---|---|---|
| POST | /api/presign |
Prepare PDF and return hash to sign | 0 |
| POST | /api/sign |
Finalize presigned PDF | 1 |
| POST | /api/sign-pfx |
Sign directly with PFX | 1 |
| POST | /api/timestamp |
Apply TSA timestamp | 1 |
| POST | /api/attachment |
Embed attachment | 1 |
| POST | /api/fill-pdf |
Fill a template with data | 1 credit / 3 pages / output |
| POST | /api/convert/pdfa |
Convert PDF to PDF/A (PDF/A-2B default) | 1 credit / 3 pages |
| POST | /api/flow |
Pipeline: fill/template + pdfa/attachment/presign/timestamp/sign-pfx | 1 per flow step; fill costs 1 / 3 pages / dataset |
| POST | /api/find-codes |
Scan for QR/DataMatrix/PDF417/Aztec | 1 credit / 3 pages |
| POST | /api/pdf-template |
Create template | 0 |
| GET | /api/pdf-template |
List templates | 0 |
| GET | /api/pdf-template/{id} |
Get template | 0 |
| PUT | /api/pdf-template/{id} |
Update template | 0 |
| DELETE | /api/pdf-template/{id} |
Delete template | 0 |
Endpoint details
Presign
POST /api/presign
Authorization: Bearer <token>
Content-Type: application/json
{
"certificatePem": "-----BEGIN CERTIFICATE-----…",
"pdfContent": "base64-pdf",
"location": "Prague, CZ",
"reason": "Approving contract",
"signRect": { "x": 50, "y": 120, "width": 200, "height": 50 },
"signPageNumber": 1,
"signImageContent": "base64-png-optional",
"fieldName": "Signature1",
"tsaUrl": "https://freetsa.org/tsr"
}
Response:
{ "id": "ef2c4d7a-…", "hashToSign": "6c3d…9f" }
Finalize signing
POST /api/sign
Authorization: Bearer <token>
Content-Type: application/json
{ "id": "ef2c4d7a-…", "signedHash": "base64-signature" }
Response:
{ "result": "base64-pdf-with-signature" }
Sign with PFX
POST /api/sign-pfx
Authorization: Bearer <token>
Content-Type: application/json
{
"pdfContent": "base64-pdf",
"pfxContent": "base64-pfx",
"pfxPassword": "password",
"location": "Prague, CZ",
"reason": "Internal approval",
"signRect": { "x": 40, "y": 100, "width": 180, "height": 45 },
"signPageNumber": 1,
"signImageContent": null,
"fieldName": "Signature1"
}
Response:
{ "result": "base64-pdf-with-signature" }
Apply timestamp
POST /api/timestamp
Authorization: Bearer <token>
Content-Type: application/json
{
"pdfContent": "base64-pdf",
"location": "Prague, CZ",
"reason": "Timestamp",
"signRect": { "x": 30, "y": 90, "width": 180, "height": 40 },
"signPageNumber": 1,
"fieldName": "Timestamp1",
"tsaUrl": "https://freetsa.org/tsr"
}
Response:
{ "result": "base64-pdf-with-timestamp" }
Add attachment
POST /api/attachment
Authorization: Bearer <token>
Content-Type: application/json
{
"pdfContent": "base64-pdf",
"attachmentContent": "base64-binary",
"fileName": "terms.pdf",
"description": "Terms and conditions",
"mimeType": "application/pdf"
}
Response:
{ "result": "base64-pdf-with-attachment" }
Convert to PDF/A
Costs 1 credit per started 3 pages. Defaults to PDF/A-2B.
Conformance options: PDF/A-1A, PDF/A-1B, PDF/A-2A, PDF/A-2B, PDF/A-2U, PDF/A-3A, PDF/A-3B, PDF/A-3U, PDF/A-4, PDF/A-4E, PDF/A-4F.
POST /api/convert/pdfa
Authorization: Bearer <token>
Content-Type: application/json
{
"pdfContent": "base64-pdf",
"conformance": "PDF/A-2B"
}
Response:
{
"result": "base64-pdf-a",
"conformance": "PDF/A-2B"
}
Flow pipeline
Run fill (optional) then a sequence of pdfa/attachment/presign/timestamp/sign-pfx. One terminal step (presign/timestamp/sign-pfx) per flow.
POST /api/flow
Authorization: Bearer <token>
Content-Type: application/json
{
"pdfContents": ["base64-pdf-1", "base64-pdf-2"],
// or "fillPdf": { "templateId": "a1b2...", "data": [ { "data": [ { "fieldName": "Name", "value": "Ada" } ] } ] },
"flow": [
{ "action": "pdfa", "data": { "conformance": "PDF/A-2B" } },
{ "action": "attachment", "data": { "attachmentContent": "base64", "fileName": "notes.txt", "mimeType": "text/plain", "description": "Notes" } },
{ "action": "presign", "data": { "certificatePem": "-----BEGIN CERTIFICATE-----…", "fieldName": "Signature1" } }
]
}
Response (start):
{ "id": "flow-id", "status": "inprogress" }
Status polling:
GET /api/flow/{flowId}
Response:
{ "id": "flow-id", "status": "waiting_for_signatures", "pendingSignatures": [ { "id": "signing-id", "hashToSign": "..." } ] }
Complete signatures (when presign used):
POST /api/flow-sign
{
"flowId": "flow-id",
"signatures": [ { "id": "signing-id", "signedHash": "base64-signature" } ]
}
Final status:
{ "id": "flow-id", "status": "done", "results": ["base64-pdf", "base64-pdf"] }
Fill PDF from template
Costs 1 credit per started 3 pages per generated output (dataset).
POST /api/fill-pdf
Authorization: Bearer <token>
Content-Type: application/json
{
"templateId": "a1b2c3d4-…",
"data": [
{ "data": [ { "fieldName": "Name", "value": "Ada" } ] },
{ "data": [ { "fieldName": "Name", "value": "Grace" } ] }
]
}
Response:
{ "files": ["base64-pdf", "base64-pdf"], "templateId": "a1b2c3d4-…" }
Find barcodes
Costs 1 credit per started 3 pages.
POST /api/find-codes
Authorization: Bearer <token>
Content-Type: application/json
{
"pdfContent": "base64-pdf",
"codeType": "any" // qr | datamatrix | pdf417 | aztec | any
}
Response:
{
"results": [
{ "value": "INV-2024-001", "codeType": "QR_CODE", "position": { "x": 212.5, "y": 412.0 }, "page": 2 }
]
}
Manage templates
// Create
POST /api/pdf-template
{
"pdfContent": "base64-pdf",
"templateName": "Invoice",
"fields": [
{ "fieldName": "Name", "page": 1, "rect": { "x": 40, "y": 700, "width": 200, "height": 32 }, "type": "text" }
]
}
// List
GET /api/pdf-template
// Get
GET /api/pdf-template/{templateId}
// Update
PUT /api/pdf-template/{templateId}
// Delete
DELETE /api/pdf-template/{templateId}
Need help? Reach out with the endpoint path, timestamp, and request ID from your logs.