OpenPrinterOpenPrinter
REST API

Create a print job

Submit an idempotent structured print job to a project printer.

Endpoint

POST /v1/projects/:projectId/jobs
Authorization: Bearer opk_your_project_key
Content-Type: application/json

The API key must include jobs:write and belong to the project in the URL.

Request body

FieldTypeDetails
printerIdstringProject printer record ID or the printer's project-local remote ID. Maximum 256 characters.
idempotencyKeystringStable application key for this logical submission. Maximum 256 characters.
documentobjectRequired structured PrintDocument; see print documents.
metadataobjectOptional string map. Keys are limited to 64 characters and values to 1,000 characters.
expiresInMssafe integerOptional requested retention duration. Defaults to 24 hours and is capped by the project's retention entitlement.
maxAttemptsintegerOptional delivery-attempt limit from 1 through 10. Defaults to 5.

The document must use protocol v1 and contain a width of 58 or 80 plus one to 256 sections. Supported section types are text, row, divider, image, qr, barcode, feed, and cut. The canonical protocol page documents each section's fields and bounds.

Example:

{
  "printerId": "printer_01",
  "idempotencyKey": "order_123_receipt_v1",
  "document": {
    "width": 80,
    "sections": [
      {
        "type": "text",
        "value": "Thank you",
        "align": "center",
        "bold": true
      },
      { "type": "divider" },
      { "type": "row", "left": "Subtotal", "right": "$12.00" },
      { "type": "qr", "value": "https://example.com/orders/123" },
      { "type": "feed", "lines": 2 },
      { "type": "cut" }
    ]
  },
  "metadata": {
    "orderId": "order_123",
    "source": "checkout"
  },
  "maxAttempts": 5
}

Responses

New jobs return 202 Accepted:

{
  "job": {
    "id": "job_01",
    "projectId": "project_01",
    "printerId": "printer_01",
    "idempotencyKey": "order_123_receipt_v1",
    "state": "PENDING",
    "metadata": {
      "orderId": "order_123"
    },
    "expiresAt": "2026-08-22T00:00:00.000Z",
    "attemptCount": 0,
    "maxAttempts": 5,
    "lastErrorCode": null,
    "lastErrorMessage": null,
    "receivedAt": null,
    "submittedAt": null,
    "createdAt": "2026-08-21T00:00:00.000Z",
    "updatedAt": "2026-08-21T00:00:00.000Z"
  },
  "duplicate": false
}

If the same project submits the same idempotencyKey again, the service returns 200 OK, the existing job, and duplicate: true. This makes a retry after a network timeout safe without an application-level duplicate guard.

The server persists the job before starting delivery. A missing printer returns 404; a disabled printer returns 409; and a project that has reached its managed monthly job entitlement returns 402 with error.code: "entitlement_limit".

On this page