Skip to main content

API Reference

Use this page when you need the current request, response, and schema details for the Bulk Fill Public API. This page is generated from the current Public API contract source.

Base URL

[
"https://api.doqlo.com"
]

Authentication

All public endpoints on this page require BF export API key Bearer auth.

Authorization: Bearer doqlo_bfexp_<public_id>.<secret>

Endpoints

POST /v1/bulkfill/export-jobs

Create a Bulk Fill export job.

Submit a Bulk Fill export request with a source PDF, a reusable .doqlo configuration package exported from the web Bulk Fill editor, exactly one row-data input, and a required failed-row threshold. Create requests require Idempotency-Key for logical replay and may include optional X-Request-Id for tracing. If X-Request-Id is missing or invalid, Doqlo generates one and returns it in the response header. .doqlo package validation remains strict for malformed, tampered, unsupported, and non-code schema-invalid packages, but accepted jobs execute best-effort against the submitted PDF. Static QR/barcode overlays that are empty, invalid, or malformed are skipped at execution time and reported in manifest.json instead of failing an accepted job. PDF-context differences are also reported in manifest.json instead of causing create-time rejection. Read Reuse .doqlo Project Files Across PDFs for the product rationale and practical examples behind this flexibility. Threshold evaluation is runtime-only: once failed rows exceed max_failed_row_percent, Doqlo aborts immediately, exposes no deliverable artifact, and does not debit quota.

Parameters:

NameInRequiredTypeDescription
Idempotency-KeyheaderYesstringCaller-provided logical create key. After a request passes auth, security checks, and front-door rate limiting, the same Idempotency-Key plus the same effective request body returns the same logical job state for 24 hours. The same key plus a different effective request body returns 409 IDEMPOTENCY_KEY_PAYLOAD_MISMATCH. The same key after 24 hours is treated as a new request. Exactly one case-sensitive value is accepted. Allowed characters: A-Z, a-z, 0-9, ., _, :, -. Length: 1..128. UUID v4 or another high-entropy random string is recommended.
X-Request-IdheaderNostringOptional tracing and support correlation ID. This header is not used for idempotency. If omitted or invalid, Doqlo generates a request ID and returns it in the response header. The same validation envelope is accepted: exactly one case-sensitive value, 1..128 characters, pattern ^[A-Za-z0-9._:-]+$.

Multipart form fields:

FieldRequiredTypeDescription
pdfYesstring (binary)Source PDF file to execute against. It does not need to exactly match .doqlo source metadata; compatible PDF-context differences are reported in manifest.json when execution still succeeds. Read Reuse .doqlo Project Files Across PDFs for practical examples of this changed-PDF behavior.
doqlo_fileYesstring (binary)Server-produced Bulk Fill .doqlo package exported from the web Bulk Fill editor. The public API executes this reusable configuration package; it does not accept field placements or mapping definitions directly.
max_failed_row_percentYesstringRequired integer percent from 0 to 100. This is your explicit acceptance boundary for failed rows. Threshold evaluation is strict failed_row_percent > max_failed_row_percent. 0 aborts on the first failed row. 100 allows all requested rows to fail without threshold failure if the manifest/container still completes. It does not switch billing to pay-per-produced-file semantics.
rows_jsonConditionalstringJSON string containing an array of row objects. Provide exactly one of rows_json or csv_file. Use object keys such as column_0, column_1, and column_2 to match the positional column IDs from your Bulk Fill layout.
csv_fileConditionalstring (binary)CSV upload. Provide exactly one of rows_json or csv_file. The public CSV contract is positional and does not auto-detect headers, so keep your mapped columns aligned to column_0, column_1, and later positions.
include_stickersNostringOptional boolean string. Current values are true or false. Omit to use false. Set this to true when you want exported PDFs to keep visual stickers or markers, including sign-related visual markers where applicable. Leave it false when you want only the generated document content without those visual markers.
flatten_formsNostringOptional boolean string. Current values are true or false. Omit to use false. Some PDFs contain interactive form fields, and generated overlays or content can otherwise appear behind those form layers. Set this to true to flatten those fields into static content so they do not cover the generated output.
delivery_modeNoresponse, webhookOptional delivery mode. Omit to use response. Use response when you want the create call to return a terminal result inline when it settles quickly. Use webhook when you want terminal completion or failure sent to your HTTPS receiver. This controls how terminal job results are delivered, not how threshold or billing semantics work.
webhook_urlNostring (uri)Required when delivery_mode=webhook. Must be a public HTTPS receiver that can accept Doqlo terminal event delivery. The URL must use HTTPS, must not include userinfo, must not target localhost or private network addresses, and must not put credentials or signatures in query parameters.
webhook_secretNostringRequired when delivery_mode=webhook. Used to sign webhook deliveries so your receiver can verify authenticity. Omit it when delivery_mode=response.

Constraints: Exactly one of the following field sets is required: rows_json | csv_file

Responses:

200

The job settled inside the sync wait window. In response mode this can include an inline completed result or a failed job envelope. In webhook mode the body can still return a completed or failed terminal job state, but webhook delivery remains the notification channel for downstream systems.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Current state of one public export job. Completed jobs can still contain partial or failed rows; inspect manifest.json in the ZIP artifact for row-level details.

Example - completed:

{
"job_id": "<job_id>",
"status": "completed",
"created_at": "<timestamp>",
"started_at": "<timestamp>",
"completed_at": "<timestamp>",
"result": {
"delivery_mode": "direct",
"download_url": "/v1/bulkfill/export-jobs/<job_id>/download",
"expires_at": "<timestamp>",
"file_size_bytes": "<file_size_bytes>"
}
}

Example - webhook_acknowledgement:

{
"job_id": "<job_id>",
"status": "completed",
"created_at": "<timestamp>",
"started_at": "<timestamp>",
"completed_at": "<timestamp>"
}

Example - webhook_threshold_failed:

{
"job_id": "<job_id>",
"status": "failed",
"created_at": "<timestamp>",
"started_at": "<timestamp>",
"completed_at": "<timestamp>",
"error": {
"code": "FAILED_ROW_THRESHOLD_EXCEEDED",
"message": "The export job exceeded max_failed_row_percent and was aborted.",
"details": {
"failure_class": "threshold_failed",
"input_row_count": 3,
"produced_row_count": 0,
"failed_row_count": 1,
"failed_row_percent": 33.3333,
"max_failed_row_percent": 0
}
}
}

202

The job was accepted but is still queued or processing. Keep the job_id and poll or wait for the terminal webhook if you chose webhook mode.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Current state of one public export job. Completed jobs can still contain partial or failed rows; inspect manifest.json in the ZIP artifact for row-level details.

400

Validation or request-shape failure, including missing or invalid Idempotency-Key (INVALID_IDEMPOTENCY_KEY).

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Standard Public API error envelope.

401

Missing or invalid BF export API key.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Standard Public API error envelope.

403

The authenticated account or key is not eligible for this request.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Standard Public API error envelope.

409

Idempotency payload mismatch for Idempotency-Key (IDEMPOTENCY_KEY_PAYLOAD_MISMATCH).

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Standard Public API error envelope.

413

Uploaded input or generated output would exceed current limits.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Standard Public API error envelope.

422

The input document or batch request could not be accepted as valid work.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: Standard Public API error envelope.

429

Rate limit exceeded, or new create requests are temporarily blocked after failure-heavy usage. These front-door protections run before idempotency replay lookup, so a retry can still return 429 before Doqlo evaluates a prior logical job.

Response headers:

HeaderTypeDescription
X-Request-Id-
Retry-AfterintegerSeconds until the next create attempt is expected to succeed. Present for fixed rate limits and temporary safeguard cooldowns.

Schema: GenericRateLimitedErrorResponse | CreateCooldownErrorResponse

500

Unexpected server-side failure, or a response-mode job that settled failed inside the sync wait window.

Response headers:

HeaderTypeDescription
X-Request-Id-

Schema: ExportJob | ErrorResponse

{
"job_id": "<job_id>",
"status": "failed",
"created_at": "<timestamp>",
"started_at": "<timestamp>",
"completed_at": "<timestamp>",
"error": {
"code": "FAILED_ROW_THRESHOLD_EXCEEDED",
"message": "The export job exceeded max_failed_row_percent and was aborted.",
"details": {
"failure_class": "threshold_failed",
"input_row_count": 3,
"produced_row_count": 0,
"failed_row_count": 1,
"failed_row_percent": 33.3333,
"max_failed_row_percent": 0
}
}
}

GET /v1/bulkfill/export-jobs/{job_id}

Read the current state of one export job.

Use this route to poll a running job or re-read the final completed or failed state. Completed jobs expose a ZIP artifact whose manifest.json reports top-level diagnostics and per-row success, partial, or failed results. Failed jobs remain readable and may include threshold diagnostics when the runtime aborted after exceeding max_failed_row_percent.

Parameters:

NameInRequiredTypeDescription
job_idpathYesstring (uuid)UUID for the accepted export job.

Responses:

200

Current job state for an owned export job.

Schema: Current state of one public export job. Completed jobs can still contain partial or failed rows; inspect manifest.json in the ZIP artifact for row-level details.

Example - completed:

{
"job_id": "<job_id>",
"status": "completed",
"created_at": "<timestamp>",
"started_at": "<timestamp>",
"completed_at": "<timestamp>",
"result": {
"delivery_mode": "direct",
"download_url": "/v1/bulkfill/export-jobs/<job_id>/download",
"expires_at": "<timestamp>",
"file_size_bytes": "<file_size_bytes>"
}
}

Example - failed:

{
"job_id": "<job_id>",
"status": "failed",
"created_at": "<timestamp>",
"completed_at": "<timestamp>",
"error": {
"code": "FAILED_ROW_THRESHOLD_EXCEEDED",
"message": "The export job exceeded max_failed_row_percent and was aborted.",
"details": {
"failure_class": "threshold_failed",
"input_row_count": 3,
"produced_row_count": 0,
"failed_row_count": 1,
"failed_row_percent": 33.3333,
"max_failed_row_percent": 0
}
}
}

400

Invalid job_id format.

Schema: Standard Public API error envelope.

401

Missing or invalid BF export API key.

Schema: Standard Public API error envelope.

403

The authenticated key is not active.

Schema: Standard Public API error envelope.

404

Job not found or not owned by the authenticated account.

Schema: Standard Public API error envelope.

429

Rate limit exceeded.

Schema: Standard Public API error envelope.

500

Unexpected server-side failure.

Schema: Standard Public API error envelope.

GET /v1/bulkfill/export-jobs/{job_id}/download

Redeem the Doqlo-controlled download handle for a completed job.

Use -L or equivalent redirect-following support in your client because Doqlo may stream the file directly or return a redirect, depending on the current delivery mode. The ZIP artifact contains one produced row PDF per successful or partial row plus manifest.json version 2 with row-level status, counts, warnings, and row-fatal errors. Threshold-failed jobs never expose this route as a deliverable artifact.

Parameters:

NameInRequiredTypeDescription
job_idpathYesstring (uuid)UUID for the completed export job.

Responses:

200

The ZIP archive is streamed directly from Doqlo.

Schema: string (binary)

302

Doqlo resolved the authenticated download and redirected the client to the current provider handoff URL.

Response headers:

HeaderTypeDescription
Locationstring (uri)Resolved provider download URL for the authenticated delivery.

400

Invalid job_id format.

Schema: Standard Public API error envelope.

401

Missing or invalid BF export API key.

Schema: Standard Public API error envelope.

403

The authenticated key is not active.

Schema: Standard Public API error envelope.

404

No active delivery is currently available for that job.

Schema: Standard Public API error envelope.

429

Rate limit exceeded.

Schema: Standard Public API error envelope.

500

The delivery exists but the current handoff failed. Retry later.

Schema: Standard Public API error envelope.

Schemas

CreateExportJobRequest

Multipart form body for a Bulk Fill export-job create request. The request uploads a reusable .doqlo configuration package, declares an explicit failed-row threshold, and executes it best-effort against the submitted PDF. Read Reuse .doqlo Project Files Across PDFs for the product rationale and practical examples behind changed-PDF reuse.

FieldRequiredTypeDescription
pdfYesstring (binary)Source PDF file to execute against. It does not need to exactly match .doqlo source metadata; compatible PDF-context differences are reported in manifest.json when execution still succeeds. Read Reuse .doqlo Project Files Across PDFs for practical examples of this changed-PDF behavior.
doqlo_fileYesstring (binary)Server-produced Bulk Fill .doqlo package exported from the web Bulk Fill editor. The public API executes this reusable configuration package; it does not accept field placements or mapping definitions directly.
max_failed_row_percentYesstringRequired integer percent from 0 to 100. This is your explicit acceptance boundary for failed rows. Threshold evaluation is strict failed_row_percent > max_failed_row_percent. 0 aborts on the first failed row. 100 allows all requested rows to fail without threshold failure if the manifest/container still completes. It does not switch billing to pay-per-produced-file semantics.
rows_jsonConditionalstringJSON string containing an array of row objects. Provide exactly one of rows_json or csv_file. Use object keys such as column_0, column_1, and column_2 to match the positional column IDs from your Bulk Fill layout.
csv_fileConditionalstring (binary)CSV upload. Provide exactly one of rows_json or csv_file. The public CSV contract is positional and does not auto-detect headers, so keep your mapped columns aligned to column_0, column_1, and later positions.
include_stickersNostringOptional boolean string. Current values are true or false. Omit to use false. Set this to true when you want exported PDFs to keep visual stickers or markers, including sign-related visual markers where applicable. Leave it false when you want only the generated document content without those visual markers.
flatten_formsNostringOptional boolean string. Current values are true or false. Omit to use false. Some PDFs contain interactive form fields, and generated overlays or content can otherwise appear behind those form layers. Set this to true to flatten those fields into static content so they do not cover the generated output.
delivery_modeNoresponse, webhookOptional delivery mode. Omit to use response. Use response when you want the create call to return a terminal result inline when it settles quickly. Use webhook when you want terminal completion or failure sent to your HTTPS receiver. This controls how terminal job results are delivered, not how threshold or billing semantics work.
webhook_urlNostring (uri)Required when delivery_mode=webhook. Must be a public HTTPS receiver that can accept Doqlo terminal event delivery. The URL must use HTTPS, must not include userinfo, must not target localhost or private network addresses, and must not put credentials or signatures in query parameters.
webhook_secretNostringRequired when delivery_mode=webhook. Used to sign webhook deliveries so your receiver can verify authenticity. Omit it when delivery_mode=response.

Constraints: Exactly one of the following field sets is required: rows_json | csv_file

ExportJob

Current state of one public export job. Completed jobs can still contain partial or failed rows; inspect manifest.json in the ZIP artifact for row-level details.

FieldRequiredTypeDescription
job_idYesstring (uuid)Accepted export-job identifier.
statusYesqueued, processing, completed, failedCurrent export-job status.
created_atYesstring (date-time)When Doqlo created the job.
started_atNostring | nullWhen processing started, when available.
completed_atNostring | nullWhen the job reached a terminal state, when available.
resultNoExportJobResultPresent only when the job completed and a current delivery record is available.
errorNoExportJobErrorPresent only when the job reached a terminal failed state.

ExportJobResult

Result payload returned for completed jobs. Use the ZIP artifact and manifest.json to understand produced, partial, failed, and skipped outcomes.

FieldRequiredTypeDescription
delivery_modeNodirect, cloudCurrent delivery handoff mode.
download_urlNostring | nullDoqlo-controlled download handle for the completed job.
expires_atNostring | nullCurrent delivery expiry timestamp.
file_size_bytesNointeger | nullCurrent ZIP size in bytes.

ExportJobError

Terminal error payload returned for failed jobs.

FieldRequiredTypeDescription
codeYesstringTerminal error code.
messageYesstringHuman-readable error message.
detailsNoThresholdFailedJobErrorDetailsThreshold-failure diagnostics exposed when the job aborted after exceeding max_failed_row_percent.

ThresholdFailedJobErrorDetails

Present when the job failed because failed rows exceeded the declared runtime threshold.

FieldRequiredTypeDescription
failure_classYesthreshold_failedStructured failure class for jobs that aborted because the declared failed-row threshold was exceeded.
input_row_countYesintegerTotal requested input rows in the job.
produced_row_countYesintegerRow PDFs produced before the job aborted.
failed_row_countYesintegerRows that failed to produce an output PDF before or at the abort point.
failed_row_percentYesnumberObserved failed-row percentage at the moment the threshold was exceeded.
max_failed_row_percentYesintegerThe customer-declared failed-row threshold for this job.

ErrorResponse

Standard Public API error envelope.

FieldRequiredTypeDescription
codeYesstringStable error code.
messageYesstringHuman-readable explanation.

GenericRateLimitedErrorResponse

Generic fixed-rate-limit denial envelope.

FieldRequiredTypeDescription
codeYesRATE_LIMITEDStable fixed-rate-limit error code.
messageYesstringHuman-readable explanation.

CreateCooldownErrorResponse

Create-only cooldown denial envelope returned after failure-heavy usage. Applies only to new create requests and does not affect status polling, downloads, or webhook delivery.

FieldRequiredTypeDescription
codeYesREPEATED_FAILED_JOBS_COOLDOWN, HIGH_FAIL_RATIO_COOLDOWNStable create-only cooldown error code.
messageYesstringHuman-readable explanation.
retry_after_secondsYesintegerSeconds until the next create attempt is expected to succeed if no new blocking conditions are introduced.