openapi: 3.0.1 info: title: PrusaLink Web description: This is a printer webservice. contact: email: link@prusa3d.cz license: name: AGPLv3 version: 1.0.0-draft externalDocs: description: Find out more about API url: http://connect.prusa3d.cz security: - digestAuth: [] paths: /api/version: get: summary: api version informations responses: 200: description: OK content: application/json: schema: $ref: "#/components/schemas/Version" 401: $ref: "#/components/responses/Unauthorized" /api/v1/info: get: summary: printer informations responses: 200: description: OK content: application/json: schema: $ref: "#/components/schemas/Info" 401: $ref: "#/components/responses/Unauthorized" /api/v1/storage: get: summary: storage info description: Returns info about each available file storage (e.g. SD Card or local storage) responses: 200: description: OK content: application/json: schema: type: object properties: storage_list: type: array items: $ref: "#/components/schemas/Storage" 401: $ref: "#/components/responses/Unauthorized" /api/v1/files/{storage}/{path}: parameters: - in: header name: Accept-Language description: Defines a language of the response schema: type: string example: "cs" - in: header name: Accept description: Preferred content-type of response - application/json or text/html, all other are returned as text/plain schema: type: string default: text/plain - in: path name: storage description: The target storage required: true schema: type: string example: "/local" - in: path name: path description: Path to the file required: true schema: type: string example: "/examples/Spice_Harvester_0.3mm_PLA_MK3S_12m.gcode" get: summary: File or folder metadata responses: 200: description: OK content: application/json: schema: oneOf: - $ref: "#/components/schemas/FileInfo" - $ref: "#/components/schemas/PrintFileInfo" - $ref: "#/components/schemas/FirmwareFileInfo" - $ref: "#/components/schemas/FolderInfo" 401: $ref: "#/components/responses/Unauthorized" put: summary: upload file or create folder parameters: - in: header name: Content-Length description: Length of file to upload schema: type: integer example: 101342 - in: header name: Content-Type description: Type of uploaded media schema: type: string default: application/octet-stream - in: header name: Print-After-Upload description: Whether to start printing the file after upload schema: type: boolean default: False - in: header name: Overwrite description: Whether to overwrite already existing files schema: type: string description: ?0=False, ?1=True, according RFC8941/3.3.6 enum: ["?0", "?1"] default: "?0" responses: 201: description: Created 401: $ref: "#/components/responses/Unauthorized" 404: $ref: "#/components/responses/NotFound" 409: $ref: "#/components/responses/Conflict" head: summary: file presence and state check responses: 200: description: OK headers: Read-Only: description: Whether the file or storage is read-only required: true schema: type: boolean example: true Currently-Printed: description: Whether this file is currently being printed required: true schema: type: boolean example: true 401: $ref: "#/components/responses/Unauthorized" 404: $ref: "#/components/responses/NotFound" 409: $ref: "#/components/responses/Conflict" delete: summary: Delete a file or folder. responses: 204: description: No Content No Error 401: $ref: "#/components/responses/Unauthorized" 404: $ref: "#/components/responses/NotFound" 409: # If the file to be deleted is currently being printed $ref: "#/components/responses/Conflict" /api/v1/cameras: get: summary: Get a list of active cameras and its properties responses: 200: description: OK content: application/json: schema: type: array items: $ref: "#/components/schemas/Camera" 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 503: $ref: "#/components/responses/ServiceUnavailable" put: summary: List of cameras in intended order requestBody: content: application/json: schema: type: array items: type: string description: Printer ID example: "sh42arta" responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 503: $ref: "#/components/responses/ServiceUnavailable" /api/v1/cameras/{id}: parameters: - in: path name: id description: ID of the camera required: true schema: type: string example: "Z42D4U2NqEX" get: summary: Get current settings and properties of specific camera responses: 200: description: OK content: application/json: schema: $ref: "#/components/schemas/CameraConfig" 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 503: $ref: "#/components/responses/ServiceUnavailable" post: summary: Setup a new camera or fix a broken one requestBody: content: application/json: schema: $ref: "#/components/schemas/CameraConfigSet" responses: 200: description: OK 400: $ref: "#/components/responses/BadRequest" 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 409: $ref: "#/components/responses/Conflict" 503: $ref: "#/components/responses/ServiceUnavailable" delete: summary: Delete a camera responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 409: $ref: "#/components/responses/Conflict" 503: $ref: "#/components/responses/ServiceUnavailable" /api/v1/cameras/snap: get: summary: Return a captured image from the default camera responses: 200: description: OK content: image/png: schema: type: string format: binary 204: description: No Content No Error 304: $ref: "#/components/responses/NotModified" 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 503: $ref: "#/components/responses/ServiceUnavailable" /api/v1/cameras/{id}/snap: parameters: - in: path name: id description: ID of the camera required: true schema: type: string example: "Z42D4U2NqEX" get: summary: Return a captured image from the camera with a given id responses: 200: description: OK content: image/png: schema: type: string format: binary 204: description: No Content No Error 304: $ref: "#/components/responses/NotModified" 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 503: $ref: "#/components/responses/ServiceUnavailable" post: summary: Make a snapshot with the camera description: Can be manually done only during camera initialization or in manual mode requestBody: content: application/json: {} responses: 200: description: OK content: image/png: schema: type: string format: binary 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 408: $ref: "#/components/responses/RequestTimeout" 409: $ref: "#/components/responses/Conflict" 503: $ref: "#/components/responses/ServiceUnavailable" /api/v1/cameras/{id}/config: parameters: - in: path name: id description: ID of the camera required: true schema: type: string example: "Z42D4U2NqEX" patch: summary: Set new settings to a working camera requestBody: content: application/json: schema: $ref: "#/components/schemas/CameraConfigSet" responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 503: $ref: "#/components/responses/ServiceUnavailable" delete: summary: Reset settings of a camera responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 503: $ref: "#/components/responses/ServiceUnavailable" /api/v1/cameras/{id}/connection: parameters: - in: path name: id description: ID of the camera required: true schema: type: string example: "Z42D4U2NqEX" post: summary: Register a camera to Connect responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 408: $ref: "#/components/responses/RequestTimeout" 409: $ref: "#/components/responses/Conflict" 503: $ref: "#/components/responses/ServiceUnavailable" delete: summary: Un-register a camera from Connect responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 403: $ref: "#/components/responses/Forbidden" 404: $ref: "#/components/responses/NotFound" 409: $ref: "#/components/responses/Conflict" 503: $ref: "#/components/responses/ServiceUnavailable" /api/v1/update/{env}: parameters: - in: path name: env description: The target environment (python or system) for update required: true schema: type: string enum: ["python"] get: summary: Retrieve information about available updates of packages and their versions responses: 200: description: OK headers: Update-Available: schema: type: boolean description: Whether there's a package update available example: true content: application/json: schema: oneOf: - $ref: "#/components/schemas/PythonPackageUpdateInfo" 204: description: No Content 401: $ref: "#/components/responses/Unauthorized" post: summary: Update packages responses: 200: description: OK 401: $ref: "#/components/responses/Unauthorized" 409: $ref: "#/components/responses/Conflict" components: schemas: Version: type: object properties: api: type: string example: "1.0.0" version: type: string example: "0.7.0" printer: type: string example: "1.3.1" text: type: string example: "PrusaLink 0.7.0" firmware: type: string example: "3.10.1-4697" sdk: type: string example: "0.7.0" capabilities: description: | Additional capabilities the printer has. The object is expected to be extended in the future with more capabilities. The absence of a capability in the object, or the complete absence of the object means the printer doesn't support such capability (probably doesn't even know such capability might exist). type: object default: {} properties: upload-by-put: description: | The printer supports uploading GCodes by the PUT method (as described in this document). It is capable of doing the PUT and HEAD to /api/v1/files/{storage}/{path} and it is capable of answering the /api/v1/storage endpoint. In absence of this capability, client MAY opt to try the legacy "octoprint" POST to /api/files/{storage}. type: boolean default: false required: - api - version - printer - text - firmware Storage: type: object properties: name: type: string example: "PrusaLink gcodes" type: type: string description: Storage source enum: ["LOCAL", "SDCARD", "USB"] path: type: string description: Path to storage (not display path) example: "/local" print_files: type: integer description: Size of all print files in bytes example: 19216842 system_files: type: integer description: Size of all system files in bytes example: 4242 free_space: type: integer description: System free space in bytes example: 1921681142 total_space: type: integer description: System total space in bytes example: 8589934592 available: type: boolean description: Whether the storage is available or not example: true read_only: type: boolean description: Whether the storage is read only example: false required: - available - path - type Camera: type: object properties: camera_id: type: string example: "sh42arta" config: type: object properties: path: type: string example: "/dev/video0" name: type: string example: "Camera L4D" driver: type: string example: "V4L2" resolution: type: string example: "1280x720" connected: type: boolean description: Camera is successfully connected to PrusaLink detected: type: boolean description: Camera is detected by PrusaLink, but not saved yet stored: type: boolean description: Camera configuration is saved in PrusaLink linked: type: boolean description: Camera is linked to PrusaConnect CameraConfig: type: object description: Camera configuration properties: name: type: string description: Name of the camera example: "MuadDib_Camera_1" trigger_scheme: type: string description: When the snapshot is taken enum: [ TEN_SEC, THIRTY_SEC, SIXTY_SEC, EACH_LAYER, FIFTH_LAYER, MANUAL ] available_resolutions: type: array items: type: object properties: width: type: integer example: 640 height: type: integer example: 480 resolution: type: object properties: width: type: integer example: 640 height: type: integer example: 480 capabilities: type: array items: type: string enum: [TRIGGER_SCHEME, IMAGING, RESOLUTION, ROTATION, EXPOSURE] CameraConfigSet: type: object description: Camera configuration to set properties: name: type: string description: Name of the camera example: "MuadDib_Camera_1" trigger_scheme: type: string description: When the snapshot is taken enum: [ TEN_SEC, THIRTY_SEC, SIXTY_SEC, EACH_LAYER, FIFTH_LAYER, MANUAL ] resolution: type: object properties: width: type: integer example: 640 height: type: integer example: 640 rotation: type: integer description: Current rotation of the output image example: 180 exposure: type: number example: 4.2 send_to_connect: type: boolean example: true GenericFileInfo: description: Basic file info object, common for all files type: object required: - name - ro - type - m_timestamp properties: name: type: string description: Short Filename example: "SPICE~1.gco" ro: type: boolean example: False size: type: integer description: Available for files only, not for folders example: 424242 type: type: string description: File could be print file, firmware file, other (e.g. configuration) file, or folder enum: [ "PRINT_FILE", "FIRMWARE", "FILE", "FOLDER" ] m_timestamp: description: Timestamp in seconds type: integer example: 1648042843 display_name: type: string description: Long Filename example: "Spice_Harvester_0.3mm_PLA_MK3S_12m.gcode" FileInfo: description: Other, not specified files info allOf: - $ref: '#/components/schemas/GenericFileInfo' - type: object properties: refs: type: object properties: download: type: string example: "/api/files/local/file.txt/raw" PrintFileInfoBasic: description: Simplified print file info within the folder's children allOf: - $ref: '#/components/schemas/GenericFileInfo' - type: object properties: refs: type: object properties: download: type: string example: "/api/files/local/examples/Spice_Harvester_0.3mm_PLA_MK3S_42m.gcode/raw" icon: type: string example: "/api/thumbnails/local/examples/Spice_Harvester_0.3mm_PLA_MK3S_42m.gcode.small.png" thumbnail: type: string example: "/api/thumbnails/local/examples/Spice_Harvester_0.3mm_PLA_MK3S_42m.gcode.orig.png" PrintFileInfo: description: Full print file info from the file's detail allOf: - $ref: '#/components/schemas/PrintFileInfoBasic' - type: object properties: meta: type: object description: Print file metadata parsed from G-code, all data are optional properties: bed_temperature: type: string description: Degrees Celsius example: "60" nozzle_temperature: type: string description: Degrees Celsius example: "215" brim_width: type: string description: Milimeters example: "0" estimated printing time (normal mode): type: string example: "42m 42s" faded_layers: type: string example: "42" filament cost: type: string example: "0.57" filament used [cm3]: type: string example: "12.44" filament used [g]: type: string example: "15.79" filament used [mm]: type: string example: "5170.06" filament_type: type: string example: "PLA" fill_density: type: string description: Percent example: "20%" initial_exposure_time: type: string description: Seconds example: "5" layer_height: type: string description: Milimeters example: "0.3" material_name: type: string example: "PLA Sandstorm Orange" exposure_time: type: string description: Seconds example: "2" max_exposure_time: type: string description: Seconds example: "3" max_initial_exposure_time: type: string description: Seconds example: "3" min_exposure_time: type: string description: Seconds example: "1" min_initial_exposure_time: type: string description: Seconds example: "1" nozzle_diameter: type: string description: Milimeters example: "0.4" print_time: type: integer description: Seconds example: "2562" printer_model: type: string enum: [ "MK3", "MK3S", "MINI" ] support_material: type: string example: "PLA" ironing: type: string example: "0" required_resin_ml: type: string example: "123.4" profile: type: string example: "ultra_fast" FirmwareFileInfoBasic: description: Simplified firmware file info within the folder's children allOf: - $ref: '#/components/schemas/GenericFileInfo' - type: object properties: refs: type: object properties: download: type: string example: "/api/files/local/firmware.hex/raw" FirmwareFileInfo: description: Full firmware file info from the file's detail allOf: - $ref: '#/components/schemas/FirmwareFileInfoBasic' - type: object properties: meta: type: object properties: version: type: string description: Firmware version in text format printer_type: type: integer printer_version: type: integer FolderInfo: description: Info about the folder and its content, except nested children allOf: - $ref: '#/components/schemas/GenericFileInfo' - type: object properties: children: type: array items: type: object description: Array of files or folders objects within the folder (excluded nested children) properties: schema: anyOf: - $ref: "#/components/schemas/FileInfo" - $ref: "#/components/schemas/PrintFileInfoBasic" - $ref: "#/components/schemas/FirmwareFileInfoBasic" - $ref: "#/components/schemas/FolderInfo" Info: type: object properties: mmu: type: boolean example: false name: type: string example: "MuadDib" location: type: string example: "Arrakis" farm_mode: type: boolean example: false nozzle_diameter: type: number example: 0.4 min_extrusion_temp: type: integer example: 170 serial: type: string example: "CZPX4720X004XC34242" sd_ready: type: boolean example: true active_camera: type: boolean example: true hostname: type: string example: "prusa-mk3.lan" port: type: string example: "/dev/tty" PythonPackageUpdateInfo: type: object properties: available_updates: type: array items: type: object properties: name: type: string description: Package name example: "paul-muaddib" version: type: string description: Current version of the package example: "1.42.1" available_version: type: string description: Available version of the package for update example: "1.42.2" path: type: string description: Path to package example: "jo/packages" Error: type: object properties: code: type: string description: Prusa error code. Must be string if we will have printer with code for example 04 example: "10108" title: type: string description: Prusa error text string with prefiled variable macros. example: "RESIN TOO LOW" text: type: string description: Prusa error text string with prefiled variable macros. example: "Measured resin volume 22.4 ml is lower than required for this print. Refill the tank and restart the print." url: type: string description: Link to the Prusa help page example: "https://help.prusa3d.com/en/10108/LHE3Q0I1" required: - title - text ResponsePlaintext: type: string default: "Project with same name has been already uploaded." description: Prusa error message (raw_message) responses: NotModified: # 304 description: Not Modified headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" BadRequest: # 400 description: Bad Request headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" Unauthorized: # 401 description: Unauthorized headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" Forbidden: # 403 description: Forbidden headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" NotFound: # 404 description: Not Found headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" RequestTimeout: # 408 description: Request Timeout headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" Conflict: # 409 description: Conflict headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" UnsupportedMediaType: # 415 description: Unsupported Media Type headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" InternalServerError: # 500 description: Internal Server Error headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" NotImplemented: # 501 description: Not Implemented headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" ServiceUnavailable: # 503 description: Service Unavailable headers: Content-Location: $ref: "#/components/headers/Content-Location" content: text/plain: schema: $ref: "#/components/schemas/ResponsePlaintext" application/json: schema: $ref: "#/components/schemas/Error" headers: Accept: required: false schema: type: string default: text/plain description: Parameter specifying supported data format from client. PCL has to support it. Slicer doesn't have to use this. If the header is not present, it defaults to text/plain Content-Location: schema: type: string default: "http:///error" description: URI path to nice error page. We can send URI to help.prusa3d.com in the future. securitySchemes: digestAuth: type: http scheme: digest