# Print API Integration Guide

> **For AI Agents:** This document is available in raw Markdown format. Replace `.html` extension with `.md` to get the raw Markdown source.
>
>
> Auto-generated [RAW AGENT.md](https://apidocs.ezeep.com/ezeepblue/api/printapi/AGENT.md) for AI-assisted and human development
>

---

## Quick Reference Table

**Base URL:** `https://printapi.ezeep.com/`

| Method | Endpoint | Description | Auth Required |
|--------|----------|-------------|---------------|
| GET | `/sfapi/GetConfiguration/` | Retrieve user details and system configuration (supported filetypes) | Yes |
| GET | `/sfapi/GetPrinter/` | Get list of printers available to the user | Yes |
| GET | `/sfapi/GetPrinterProperties/` | Get detailed properties of a printer by ID or name | Yes |
| GET | `/sfapi/PrepareUpload/` | Prepare file upload and get sasUri for uploading | Yes |
| PUT | `{{sasUri}}` | Upload file to Azure blob storage | No (uses sasUri token) |
| POST | `/sfapi/Print/` | Print an uploaded file or file referenced by URL | Yes |
| GET | `/sfapi/Status/?id=:id` | Get print job status | Yes |

---

## Authentication

### Auth Type  
**OAuth 2.0** with **Bearer Token**

ezeep Blue supports the following authorization flows:  
- **Authorization Code Flow** - Recommended for secure server-side apps  
- **Authorization Code Flow with PKCE** - For SPAs, mobile apps, desktop applications  
- **Device Authorization Flow (Pairing Code Grant)** - For CLI tools, scripts, devices without browser 
- **Resource Owner Password Credentials** - Legacy, not recommended 
- **Client Credentials** - Server-to-server (UMP customers only)  

### Authorization Base URL
```
https://account.ezeep.com/
```

### Header Format

**API Requests (Bearer Token)**
```
Authorization: Bearer <access_token>
```

**Token Requests (Basic Auth)**
```
Authorization: Basic <base64_encoded_client_credentials>
```

**Encoding format:**
- Public client (no secret): `base64("<client_id>:")`
- Confidential client: `base64("<client_id>:<client_secret>")`

### Token Lifecycle

| Token Type | Expiration | Refresh Mechanism |
|------------|------------|-------------------|
| Access Token | 3600 seconds (1 hour) | Use refresh token to obtain new access token |
| Refresh Token | Varies by configuration | Token rotation: new refresh token issued with each use |

**Important:** With refresh token rotation enabled, each refresh token is single-use. Store the new refresh token from each response.

### Available Scopes

| Scope | Description |
|-------|-------------|
| `printing` | Access to printing APIs |
| `printing.connectors` | Access to connector APIs |
| `reporting` | Access to reporting APIs |
| `accounts` | Access to account APIs |
| `accounts.me` | Access to current user account |

---

## Authentication Code Snippets

### 1. Initiate Authorization (Browser Redirect)

```shell
# Open in browser - user will authenticate and be redirected with authorization code
https://account.ezeep.com/oauth/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>&scope=printing
```

### 2. Exchange Authorization Code for Tokens

```shell
curl -X POST "https://account.ezeep.com/oauth/access_token/" \
     --header "Authorization: Basic <base64_encoded_client_id>" \
     --header "Content-Type: application/x-www-form-urlencoded" \
     --data "grant_type=authorization_code" \
     --data "scope=printing" \
     --data "code=<authorization_code>" \
     --data "redirect_uri=<your_redirect_uri>"
```

**Response:**

```json
{
  "access_token": "eyJ0eXAiO...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "printing",
  "refresh_token": "erliDdAb..."
}
```

### 3. Refresh Access Token

```shell
curl -X POST "https://account.ezeep.com/oauth/access_token/" \
     --header "Authorization: Basic <base64_encoded_client_id>" \
     --header "Content-Type: application/x-www-form-urlencoded" \
     --data "grant_type=refresh_token" \
     --data "scope=printing" \
     --data "refresh_token=<your_refresh_token>"
```

### Base64 Encoding Helper

```shell
# Public client (no secret)
echo -n "<client_id>:" | base64

# Confidential client (with secret)
echo -n "<client_id>:<client_secret>" | base64
```

> **Note:** The base64 encoded string length must be a multiple of 4. Pad with `=` if needed.

---

## API Endpoints

### GET /sfapi/GetConfiguration/

Retrieve details of the currently authenticated user and related system configuration parameters. Used to determine supported filetypes for printing.

**Request:**

```shell
curl -X GET "https://printapi.ezeep.com/sfapi/GetConfiguration/" \
     --header "Authorization: Bearer <access_token>"
```

**Response:**

```json
{
  "Drivers": {
    "PrinterDynamic": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
    "PrinterStatic": "f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3"
  },
  "Folders": [
    {
      "export": "",
      "id": 1,
      "op": 3
    }
  ],
  "SFForms": {
    "$Count": 0
  },
  "Shell": [],
  "System": {
    "BW": 0,
    "CONNECT": ":4001",
    "CONNECTEX": ":4001",
    "DocProvUplInterval": 60,
    "FILEEXT": "bmp;csv;doc;docm;docx;dot;dotm;dotx;eml;gif;htm;html;jpeg;jpg;log;mht;mhtml;odf;odg;odm;odp;odt;otg;oth;otp;ott;pdf;png;pot;potm;potx;pps;ppsx;ppt;pptm;pptx;rtf;scp;sda;sdd;sds;sdw;sgl;smf;sti;stw;sxd;sxg;sxi;sxm;sxw;tif;tiff;tpf;txt;vor;wtx;xls;xlsb;xlsm;xlsx;xlt;xltm;xltx;xml;xps;",
    "HOST": "https://vm-example-host:443",
    "HOSTEX": "https://vm-example-host:443",
    "MaxLocalPreviewFileSize": 16777216
  }
}
```

**Response Fields:**

| Section | Attribute | Type | Description |
|---------|-----------|------|-------------|
| `System` | `FILEEXT` | string | List of supported file formats (semicolon-separated extensions) |

---

### GET /sfapi/GetPrinter/

Returns a list of printers available to the authenticated user.

**Request:**

```shell
curl -X GET "https://printapi.ezeep.com/sfapi/GetPrinter/" \
     --header "Authorization: Bearer <access_token>"
```

**Response:**

```json
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "location": "Building A, Floor 2",
    "name": "printer 6"
  },
  {
    "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "location": "",
    "name": "printer01"
  }
]
```

**Response Fields:**

| Attribute | Type | Description |
|-----------|------|-------------|
| `id` | string (UUID) | Unique printer identifier |
| `location` | string | Physical location of printer |
| `name` | string | Display name of printer |

---

### GET /sfapi/GetPrinterProperties/

Returns detailed properties of a printer by ID or name.

**Endpoints:**
```
GET /sfapi/GetPrinterProperties/
GET /sfapi/GetPrinterProperties/?id=<printer_uuid>
GET /sfapi/GetPrinterProperties/?printer=<printer_name>
```

**Parameters:**

| Attribute | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | No | UUID of the printer |
| `printer` | string | No | Name of the printer |

> **Note:** If neither parameter is provided, returns properties for all available printers. Specify either `printer` or `id`, not both.

**Request:**

```shell
curl -X GET "https://printapi.ezeep.com/sfapi/GetPrinterProperties/?id=c3d4e5f6-a7b8-9012-cdef-123456789012" \
     --header "Authorization: Bearer <access_token>"
```

**Response:**

```json
[{
    "Collate": true,
    "Color": false,
    "ColorSupported": true,
    "Driver": "TP Output Gateway",
    "DuplexMode": 2,
    "DuplexSupported": true,
    "Id": "d4e5f6a7-b8c9-0123-def0-234567890123",
    "Location": "",
    "MediaSupported": ["Auto", "Letter", "Legal", "Statement", "Executive", "A5", "B5", "A4", "Envelope Monarch", "Envelope No. 10 (COM10)", "Envelope DL", "Envelope C5", "Custom [Name Fixed]"],
    "MediaSupportedId": [0, 1, 5, 6, 7, 11, 13, 9, 37, 20, 27, 28, 256],
    "Name": "Canon UFR II Printer",
    "OrientationsSupported": ["portrait", "landscape"],
    "OrientationsSupportedId": [1, 2],
    "PaperFormats": [
        {"Id": 1, "Name": "Letter", "XRes": 2159, "YRes": 2794, "Default": false},
        {"Id": 5, "Name": "Legal", "XRes": 2159, "YRes": 3556, "Default": false},
        {"Id": 9, "Name": "A4", "XRes": 2100, "YRes": 2970, "Default": true},
        {"Id": 27, "Name": "Envelope DL2", "XRes": 1100, "YRes": 2200, "Default": false},
        {"Id": 28, "Name": "Envelope C5", "XRes": 1620, "YRes": 2290, "Default": false}
    ],
    "Default": {
        "Duplex": "duplex_simplex",
        "DuplexIndex": 1,
        "Color": "color",
        "Orientation": null,
        "OrientationIndex": null,
        "Resolution": "600",
        "Paper": "A4",
        "PaperId": 9,
        "Tray": "Multi-Purpose Feeder",
        "TrayIndex": 284
    },
    "Resolutions": ["Auto", "600"],
    "TPUID": 2,
    "Trays": [
        {"Index": 284, "Name": "Multi-Purpose Feeder", "Default": true},
        {"Index": 285, "Name": "Manual Paper", "Default": false},
        {"Index": 286, "Name": "Envelope Feeder", "Default": false}
    ]
}]
```

**Response Fields:**

| Attribute | Type | Description |
|-----------|------|-------------|
| `Id` | string (UUID) | Printer identifier |
| `Name` | string | Printer name |
| `Location` | string | Printer location |
| `ColorSupported` | bool | Whether color printing is supported |
| `DuplexSupported` | bool | Whether duplex printing is supported |
| `DuplexMode` | int | Current duplex mode |
| `MediaSupported` | array | List of supported paper sizes |
| `MediaSupportedId` | array | IDs corresponding to paper sizes |
| `OrientationsSupported` | array | Supported orientations |
| `OrientationsSupportedId` | array | IDs for orientations (1=portrait, 2=landscape) |
| `PaperFormats` | array | Detailed paper format specifications |
| `Resolutions` | array | Supported print resolutions |
| `Trays` | array | Available paper trays |
| `Default` | object | Default printer settings |

> **Reference:** ezeep follows Microsoft's DEVMODE for printer properties. See [DEVMODE specification](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-devmodea).

---

### GET /sfapi/PrepareUpload/

Prepares a file upload by generating a file ID and Azure SAS URI.

**Request:**

```shell
curl -X GET "https://printapi.ezeep.com/sfapi/PrepareUpload/" \
     --header "Authorization: Bearer <access_token>"
```

**Response:**

```json
{
  "fileid": "ERI_e1f2a3b4-c5d6-7890-abcd-ef0123456789",
  "sasUri": "https://examplestore.blob.core.windows.net/userstorage/ERI_e1f2a3b4-c5d6-7890-abcd-ef0123456789?sv=2018-03-28&sr=b&sig=ExAmPlEsIgNaTuReStRiNg1234567890ABCDEF%3D&se=2024-01-01T12%3A00%3A00Z&sp=wl"
}
```

**Response Fields:**

| Attribute | Type | Description |
|-----------|------|-------------|
| `fileid` | string | Unique file identifier for print requests |
| `sasUri` | string | Azure Blob Storage SAS URI for file upload |

---

### PUT {{sasUri}} - File Upload

Uploads a file to Azure Blob Storage using the SAS URI from PrepareUpload.

**Request:**

```shell
curl -X PUT "<sasUri>" \
     --header "x-ms-blob-type: BlockBlob" \
     --header "Content-Type: multipart/form-data" \
     -F "file=@/path/to/your/file.pdf"
```

**Headers:**

| Header | Value | Description |
|--------|-------|-------------|
| `x-ms-blob-type` | `BlockBlob` | Required Azure blob type |
| `Content-Type` | `multipart/form-data` | Content type for file upload |

**Response:**
- **HTTP 201 Created** - File uploaded successfully (empty response body)

---

### POST /sfapi/Print/

Prints an uploaded file or a file referenced by URL.

**Request:**

```shell
curl -X POST "https://printapi.ezeep.com/sfapi/Print/" \
     --header "Content-Type: application/json" \
     --header "Authorization: Bearer <access_token>" \
     --data '{
         "fileid": "<fileid>",
         "printerid": "<printerid>",
         "type": "pdf"
     }'
```

**Parameters (Uploaded File):**

| Attribute | Type | Required | Description |
|-----------|------|----------|-------------|
| `fileid` | string | Yes | ID of the uploaded file from PrepareUpload |
| `type` | string | Yes | File type/extension (e.g., "pdf", "txt") |
| `printerid` | string | Yes | ID of the printer from GetPrinter |
| `alias` | string | No | Original filename (defaults to fileid) |
| `printanddelete` | bool | No | Delete file after printing (default: false) |
| `paperid` | int | No | Paper size ID from GetPrinterProperties |
| `paperlength` | int | No | Custom paper length in tenths of mm (if paperid=256) |
| `paperwidth` | int | No | Custom paper width in tenths of mm (if paperid=256) |
| `color` | bool | No | Enable color printing |
| `duplex` | bool | No | Enable duplex printing |
| `duplexmode` | int | No | Duplex mode |
| `orientation` | int | No | Orientation ID (1=portrait, 2=landscape) |
| `copies` | int | No | Number of copies |
| `resolution` | string | No | DPI / quality |
| `trayname` | string | No | Tray name |
| `defaultsource` | int | No | Tray index (overrides trayname) |
| `locale` | string | No | Language settings (e.g., "de-DE", "en-US") |
| `pageRanges` | string | No | Page ranges (e.g., "1-2,4-5", "1,2,3") |

**Parameters (URL-Referenced File):**

| Attribute | Type | Required | Description |
|-----------|------|----------|-------------|
| `fileurl` | string | Yes | Public URL of the file to print |
| `type` | string | Yes | File type/extension |
| `printerid` | string | Yes | ID of the printer |
| *(other params)* | | | Same as uploaded file parameters |

**Example Request (URL-Referenced File):**

```shell
curl -X POST "https://printapi.ezeep.com/sfapi/Print/" \
     --header "Content-Type: application/json" \
     --header "Authorization: Bearer <access_token>" \
     --data '{
         "fileurl": "https://example.com/document.pdf",
         "printerid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
         "type": "pdf",
         "properties": {"OrientationsSupported": "landscape", "MediaSupported": "Letter"}
     }'
```

**Response (Success):**

```json
{
  "jobid": "ezprnds-d000001:Example_Printer#1234567890:1"
}
```

**Response (File Still Uploading - HTTP 412):**

```json
{
  "fileid": "ERI_e1f2a3b4-c5d6-7890-abcd-ef0123456789",
  "sasUri": ""
}
```

> **Note:** For large files referenced by URL, you may receive HTTP 412. Use the returned `fileid` with the standard print endpoint to retry.

---

### GET /sfapi/Status/

Retrieves the current status of a print job.

**Request:**

```shell
curl -X GET "https://printapi.ezeep.com/sfapi/Status/?id=<jobid>" \
     --header "Authorization: Bearer <access_token>"
```

**Parameters:**

| Attribute | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | Job identifier from Print response |

**Response:**

```json
{
  "jobpagesprinted": 0,
  "jobpagestotal": 1,
  "jobposition": 1,
  "jobstatus": 129,
  "jobstatusstring": "PRINTING|RETAINED|"
}
```

**Response Fields:**

| Attribute | Type | Description |
|-----------|------|-------------|
| `jobpagesprinted` | int | Pages printed so far |
| `jobpagestotal` | int | Total pages in job |
| `jobposition` | int | Position in print queue |
| `jobstatus` | int | Status code |
| `jobstatusstring` | string | Human-readable status |

---

## Status Codes

| Status Code | Description |
|-------------|-------------|
| 0 | SUCCESS: Print job successfully finished |
| 2 | ERROR: Invalid print job identifier |
| 129 | INFO: Print job processing is running |
| 1246 | INFO: No status available yet, keep polling |
| 3011 | ERROR: Something went wrong - restart print job |

---
## Error Codes

ezeep uses Microsoft error codes represented as integers. See https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes for a comprehensive list.

## Common Integration Patterns

### Pattern 1: Upload and Print

```shell
# 1. Prepare upload
UPLOAD_RESPONSE=$(curl -s -X GET "https://printapi.ezeep.com/sfapi/PrepareUpload/" \
     --header "Authorization: Bearer $ACCESS_TOKEN")

FILEID=$(echo $UPLOAD_RESPONSE | jq -r '.fileid')
SASURI=$(echo $UPLOAD_RESPONSE | jq -r '.sasUri')

# 2. Upload file
curl -X PUT "$SASURI" \
     --header "x-ms-blob-type: BlockBlob" \
     --header "Content-Type: multipart/form-data" \
     -F "file=@document.pdf"

# 3. Print
curl -X POST "https://printapi.ezeep.com/sfapi/Print/" \
     --header "Content-Type: application/json" \
     --header "Authorization: Bearer $ACCESS_TOKEN" \
     --data "{\"fileid\":\"$FILEID\",\"printerid\":\"$PRINTER_ID\",\"type\":\"pdf\"}"
```

### Pattern 2: Print from URL

```shell
curl -X POST "https://printapi.ezeep.com/sfapi/Print/" \
     --header "Content-Type: application/json" \
     --header "Authorization: Bearer $ACCESS_TOKEN" \
     --data '{
         "fileurl": "https://public-url.com/document.pdf",
         "printerid": "'"$PRINTER_ID"'",
         "type": "pdf"
     }'
```

### Pattern 3: Poll Job Status

```shell
while true; do
    STATUS=$(curl -s -X GET "https://printapi.ezeep.com/sfapi/Status/?id=$JOB_ID" \
         --header "Authorization: Bearer $ACCESS_TOKEN")

    STATUS_CODE=$(echo $STATUS | jq -r '.jobstatus')

    case $STATUS_CODE in
        0) echo "Print completed successfully"; break ;;
        129|1246) echo "Printing in progress..."; sleep 2 ;;
        *) echo "Error: $STATUS_CODE"; break ;;
    esac
done
```

---

## Supported File Types

The following file extensions are supported for printing (retrieved via GetConfiguration):

**Documents:** doc, docm, docx, dot, dotm, dotx, odf, odg, odm, odp, odt, otg, oth, otp, ott, pdf, rtf, txt, xps

**Spreadsheets:** csv, xls, xlsb, xlsm, xlsx, xlt, xltm, xltx

**Presentations:** pot, potm, potx, pps, ppsx, ppt, pptm, pptx, sda, sdd, sds, sdw

**Images:** bmp, gif, jpeg, jpg, png, tif, tiff

**Web/Email:** eml, htm, html, mht, mhtml, xml

**Other:** log, scp, sgl, smf, sti, stw, sxd, sxg, sxi, sxm, sxw, tpf, vor, wtx
